1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2015 The Chromium Authors. All rights reserved.
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/trace_event/trace_config.h"
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
7cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stddef.h>
8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <utility>
10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/json/json_reader.h"
12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/json/json_writer.h"
13cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/strings/pattern.h"
14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/string_split.h"
15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/string_tokenizer.h"
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/strings/stringprintf.h"
17cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/trace_event/memory_dump_manager.h"
18cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "base/trace_event/memory_dump_request_args.h"
19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/trace_event/trace_event.h"
20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base {
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace trace_event {
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace {
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// String options that can be used to initialize TraceOptions.
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kRecordUntilFull[] = "record-until-full";
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kRecordContinuously[] = "record-continuously";
29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kTraceToConsole[] = "trace-to-console";
31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableSampling[] = "enable-sampling";
32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableSystrace[] = "enable-systrace";
33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableArgumentFilter[] = "enable-argument-filter";
34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// String parameters that can be used to parse the trace config string.
36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kRecordModeParam[] = "record_mode";
37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableSamplingParam[] = "enable_sampling";
38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableSystraceParam[] = "enable_systrace";
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kEnableArgumentFilterParam[] = "enable_argument_filter";
40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kIncludedCategoriesParam[] = "included_categories";
41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kExcludedCategoriesParam[] = "excluded_categories";
42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kSyntheticDelaysParam[] = "synthetic_delays";
43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char kSyntheticDelayCategoryFilterPrefix[] = "DELAY(";
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
46cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// String parameters that is used to parse memory dump config in trace config
47cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// string.
48cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst char kMemoryDumpConfigParam[] = "memory_dump_config";
49cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst char kTriggersParam[] = "triggers";
50cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst char kPeriodicIntervalParam[] = "periodic_interval_ms";
51cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst char kModeParam[] = "mode";
52cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
53cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// Default configuration of memory dumps.
54cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst TraceConfig::MemoryDumpTriggerConfig kDefaultHeavyMemoryDumpTrigger = {
55cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    2000,  // periodic_interval_ms
56cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    MemoryDumpLevelOfDetail::DETAILED};
57cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoconst TraceConfig::MemoryDumpTriggerConfig kDefaultLightMemoryDumpTrigger = {
58cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    250,  // periodic_interval_ms
59cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    MemoryDumpLevelOfDetail::LIGHT};
60cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
61cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass ConvertableTraceConfigToTraceFormat
62cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    : public base::trace_event::ConvertableToTraceFormat {
63cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko public:
64cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config)
65cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      : trace_config_(trace_config) {}
66cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  void AppendAsTraceFormat(std::string* out) const override {
67cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    out->append(trace_config_.ToString());
68cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
69cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
70cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko protected:
71cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  ~ConvertableTraceConfigToTraceFormat() override {}
72cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko private:
74cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  const TraceConfig trace_config_;
75cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko};
76cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace
78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::TraceConfig() {
80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  InitializeDefault();
81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::TraceConfig(const std::string& category_filter_string,
84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                         const std::string& trace_options_string) {
85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  InitializeFromStrings(category_filter_string, trace_options_string);
86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::TraceConfig(const std::string& category_filter_string,
89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                         TraceRecordMode record_mode) {
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string trace_options_string;
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  switch (record_mode) {
92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_UNTIL_FULL:
93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      trace_options_string = kRecordUntilFull;
94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_CONTINUOUSLY:
96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      trace_options_string = kRecordContinuously;
97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_AS_MUCH_AS_POSSIBLE:
99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      trace_options_string = kRecordAsMuchAsPossible;
100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case ECHO_TO_CONSOLE:
102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      trace_options_string = kTraceToConsole;
103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    default:
105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      NOTREACHED();
106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  InitializeFromStrings(category_filter_string, trace_options_string);
108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::TraceConfig(const std::string& config_string) {
111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!config_string.empty())
112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    InitializeFromConfigString(config_string);
113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    InitializeDefault();
115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::TraceConfig(const TraceConfig& tc)
118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    : record_mode_(tc.record_mode_),
119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      enable_sampling_(tc.enable_sampling_),
120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      enable_systrace_(tc.enable_systrace_),
121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      enable_argument_filter_(tc.enable_argument_filter_),
122cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      memory_dump_config_(tc.memory_dump_config_),
123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      included_categories_(tc.included_categories_),
124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      disabled_categories_(tc.disabled_categories_),
125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      excluded_categories_(tc.excluded_categories_),
126cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      synthetic_delays_(tc.synthetic_delays_) {}
127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig::~TraceConfig() {
129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratTraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (this == &rhs)
133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return *this;
134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  record_mode_ = rhs.record_mode_;
136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_sampling_ = rhs.enable_sampling_;
137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_systrace_ = rhs.enable_systrace_;
138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_argument_filter_ = rhs.enable_argument_filter_;
139cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_ = rhs.memory_dump_config_;
140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  included_categories_ = rhs.included_categories_;
141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  disabled_categories_ = rhs.disabled_categories_;
142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_ = rhs.excluded_categories_;
143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  synthetic_delays_ = rhs.synthetic_delays_;
144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return *this;
145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst TraceConfig::StringList& TraceConfig::GetSyntheticDelayValues() const {
148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return synthetic_delays_;
149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string TraceConfig::ToString() const {
152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  base::DictionaryValue dict;
153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  ToDict(dict);
154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string json;
156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  base::JSONWriter::Write(dict, &json);
157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return json;
159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
160b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
161cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoscoped_refptr<ConvertableToTraceFormat>
162cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoTraceConfig::AsConvertableToTraceFormat() const {
163cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  return new ConvertableTraceConfigToTraceFormat(*this);
164cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}
165cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string TraceConfig::ToCategoryFilterString() const {
167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string filter_string;
168b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  WriteCategoryFilterString(included_categories_, &filter_string, true);
169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  WriteCategoryFilterString(disabled_categories_, &filter_string, true);
170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  WriteCategoryFilterString(excluded_categories_, &filter_string, false);
171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  WriteCategoryFilterString(synthetic_delays_, &filter_string);
172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return filter_string;
173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool TraceConfig::IsCategoryGroupEnabled(
176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const char* category_group_name) const {
177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // TraceLog should call this method only as part of enabling/disabling
178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // categories.
179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool had_enabled_by_default = false;
181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  DCHECK(category_group_name);
182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  CStringTokenizer category_group_tokens(
183b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      category_group_name, category_group_name + strlen(category_group_name),
184b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      ",");
185b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  while (category_group_tokens.GetNext()) {
186b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::string category_group_token = category_group_tokens.token();
187b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Don't allow empty tokens, nor tokens with leading or trailing space.
188b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    DCHECK(!TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
189b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat               category_group_token))
190b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        << "Disallowed category string";
191b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (IsCategoryEnabled(category_group_token.c_str())) {
192b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return true;
193b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
194cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!base::MatchPattern(category_group_token.c_str(),
195cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                            TRACE_DISABLED_BY_DEFAULT("*")))
196b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      had_enabled_by_default = true;
197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Do a second pass to check for explicitly disabled categories
199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // (those explicitly enabled have priority due to first pass).
200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  category_group_tokens.Reset();
201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool category_group_disabled = false;
202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  while (category_group_tokens.GetNext()) {
203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::string category_group_token = category_group_tokens.token();
204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    for (StringList::const_iterator ci = excluded_categories_.begin();
205b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat         ci != excluded_categories_.end();
206b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat         ++ci) {
207cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (base::MatchPattern(category_group_token.c_str(), ci->c_str())) {
208b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // Current token of category_group_name is present in excluded_list.
209b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // Flag the exclusion and proceed further to check if any of the
210b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // remaining categories of category_group_name is not present in the
211b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // excluded_ list.
212b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        category_group_disabled = true;
213b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        break;
214b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      }
215b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      // One of the category of category_group_name is not present in
216cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      // excluded_ list. So, if it's not a disabled-by-default category,
217cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      // it has to be included_ list. Enable the category_group_name
218cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      // for recording.
219cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      if (!base::MatchPattern(category_group_token.c_str(),
220cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                              TRACE_DISABLED_BY_DEFAULT("*"))) {
221cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        category_group_disabled = false;
222cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      }
223b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
224b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // One of the categories present in category_group_name is not present in
225b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // excluded_ list. Implies this category_group_name group can be enabled
226b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // for recording, since one of its groups is enabled for recording.
227b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (!category_group_disabled)
228b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
229b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
230b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // If the category group is not excluded, and there are no included patterns
231b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // we consider this category group enabled, as long as it had categories
232b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // other than disabled-by-default.
233b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return !category_group_disabled &&
234b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat         included_categories_.empty() && had_enabled_by_default;
235b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
236b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
237b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::Merge(const TraceConfig& config) {
238b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (record_mode_ != config.record_mode_
239b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      || enable_sampling_ != config.enable_sampling_
240b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      || enable_systrace_ != config.enable_systrace_
241b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      || enable_argument_filter_ != config.enable_argument_filter_) {
242b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    DLOG(ERROR) << "Attempting to merge trace config with a different "
243b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                << "set of options.";
244b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
245b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
246b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Keep included patterns only if both filters have an included entry.
247b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Otherwise, one of the filter was specifying "*" and we want to honor the
248b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // broadest filter.
249b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (HasIncludedPatterns() && config.HasIncludedPatterns()) {
250b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    included_categories_.insert(included_categories_.end(),
251b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                config.included_categories_.begin(),
252b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                config.included_categories_.end());
253b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  } else {
254b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    included_categories_.clear();
255b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
256b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
257cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.insert(memory_dump_config_.end(),
258cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                             config.memory_dump_config_.begin(),
259cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                             config.memory_dump_config_.end());
260cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
261b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  disabled_categories_.insert(disabled_categories_.end(),
262b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                              config.disabled_categories_.begin(),
263b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                              config.disabled_categories_.end());
264b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_.insert(excluded_categories_.end(),
265b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                              config.excluded_categories_.begin(),
266b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                              config.excluded_categories_.end());
267b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  synthetic_delays_.insert(synthetic_delays_.end(),
268b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                           config.synthetic_delays_.begin(),
269b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                           config.synthetic_delays_.end());
270b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
271b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
272b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::Clear() {
273b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  record_mode_ = RECORD_UNTIL_FULL;
274b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_sampling_ = false;
275b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_systrace_ = false;
276b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_argument_filter_ = false;
277b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  included_categories_.clear();
278b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  disabled_categories_.clear();
279b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_.clear();
280b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  synthetic_delays_.clear();
281cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.clear();
282b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
283b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
284b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::InitializeDefault() {
285b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  record_mode_ = RECORD_UNTIL_FULL;
286b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_sampling_ = false;
287b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_systrace_ = false;
288b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_argument_filter_ = false;
289b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_.push_back("*Debug");
290b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_.push_back("*Test");
291b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
292b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
293b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::InitializeFromConfigString(const std::string& config_string) {
294b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  scoped_ptr<base::Value> value(base::JSONReader::Read(config_string));
295b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
296b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    InitializeDefault();
297b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return;
298b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
299b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  scoped_ptr<base::DictionaryValue> dict(
300b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        static_cast<base::DictionaryValue*>(value.release()));
301b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
302b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  record_mode_ = RECORD_UNTIL_FULL;
303b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string record_mode;
304b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (dict->GetString(kRecordModeParam, &record_mode)) {
305b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (record_mode == kRecordUntilFull) {
306b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      record_mode_ = RECORD_UNTIL_FULL;
307b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    } else if (record_mode == kRecordContinuously) {
308b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      record_mode_ = RECORD_CONTINUOUSLY;
309b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    } else if (record_mode == kTraceToConsole) {
310b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      record_mode_ = ECHO_TO_CONSOLE;
311b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    } else if (record_mode == kRecordAsMuchAsPossible) {
312b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
313b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
314b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
315b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
316b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool enable_sampling;
317b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!dict->GetBoolean(kEnableSamplingParam, &enable_sampling))
318b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_sampling_ = false;
319b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
320b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_sampling_ = enable_sampling;
321b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
322b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool enable_systrace;
323b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!dict->GetBoolean(kEnableSystraceParam, &enable_systrace))
324b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_systrace_ = false;
325b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
326b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_systrace_ = enable_systrace;
327b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
328b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool enable_argument_filter;
329b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!dict->GetBoolean(kEnableArgumentFilterParam, &enable_argument_filter))
330b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_argument_filter_ = false;
331b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
332b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    enable_argument_filter_ = enable_argument_filter;
333b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
334cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  base::ListValue* category_list = nullptr;
335b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (dict->GetList(kIncludedCategoriesParam, &category_list))
336b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    SetCategoriesFromIncludedList(*category_list);
337b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (dict->GetList(kExcludedCategoriesParam, &category_list))
338b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    SetCategoriesFromExcludedList(*category_list);
339b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (dict->GetList(kSyntheticDelaysParam, &category_list))
340b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    SetSyntheticDelaysFromList(*category_list);
341cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
342cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
343cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    // If dump triggers not set, the client is using the legacy with just
344cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    // category enabled. So, use the default periodic dump config.
345cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    base::DictionaryValue* memory_dump_config = nullptr;
346cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (dict->GetDictionary(kMemoryDumpConfigParam, &memory_dump_config))
347cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      SetMemoryDumpConfig(*memory_dump_config);
348cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    else
349cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      SetDefaultMemoryDumpConfig();
350cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
351b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
352b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
353b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::InitializeFromStrings(
354b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const std::string& category_filter_string,
355b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const std::string& trace_options_string) {
356b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!category_filter_string.empty()) {
357cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    std::vector<std::string> split = base::SplitString(
358cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        category_filter_string, ",", base::TRIM_WHITESPACE,
359cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        base::SPLIT_WANT_ALL);
360b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::vector<std::string>::iterator iter;
361b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    for (iter = split.begin(); iter != split.end(); ++iter) {
362b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      std::string category = *iter;
363b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      // Ignore empty categories.
364b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      if (category.empty())
365b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        continue;
366b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      // Synthetic delays are of the form 'DELAY(delay;option;option;...)'.
367b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      if (category.find(kSyntheticDelayCategoryFilterPrefix) == 0 &&
368b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          category.at(category.size() - 1) == ')') {
369b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        category = category.substr(
370b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            strlen(kSyntheticDelayCategoryFilterPrefix),
371b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            category.size() - strlen(kSyntheticDelayCategoryFilterPrefix) - 1);
372b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        size_t name_length = category.find(';');
373b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        if (name_length != std::string::npos && name_length > 0 &&
374b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat            name_length != category.size() - 1) {
375b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          synthetic_delays_.push_back(category);
376b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        }
377b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (category.at(0) == '-') {
378b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // Excluded categories start with '-'.
379b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        // Remove '-' from category string.
380b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        category = category.substr(1);
381b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        excluded_categories_.push_back(category);
382b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
383b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                  TRACE_DISABLED_BY_DEFAULT("")) == 0) {
384b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        disabled_categories_.push_back(category);
385b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else {
386b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        included_categories_.push_back(category);
387b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      }
388b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
389b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
390b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
391b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  record_mode_ = RECORD_UNTIL_FULL;
392b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_sampling_ = false;
393b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_systrace_ = false;
394b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  enable_argument_filter_ = false;
395b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if(!trace_options_string.empty()) {
396cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    std::vector<std::string> split = base::SplitString(
397cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        trace_options_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
398b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::vector<std::string>::iterator iter;
399b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    for (iter = split.begin(); iter != split.end(); ++iter) {
400b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      if (*iter == kRecordUntilFull) {
401b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        record_mode_ = RECORD_UNTIL_FULL;
402b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kRecordContinuously) {
403b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        record_mode_ = RECORD_CONTINUOUSLY;
404b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kTraceToConsole) {
405b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        record_mode_ = ECHO_TO_CONSOLE;
406b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kRecordAsMuchAsPossible) {
407b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
408b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kEnableSampling) {
409b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        enable_sampling_ = true;
410b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kEnableSystrace) {
411b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        enable_systrace_ = true;
412b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      } else if (*iter == kEnableArgumentFilter) {
413b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        enable_argument_filter_ = true;
414b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      }
415b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
416b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
417cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
418cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
419cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    SetDefaultMemoryDumpConfig();
420cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
421b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
422b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
423b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::SetCategoriesFromIncludedList(
424b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const base::ListValue& included_list) {
425b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  included_categories_.clear();
426b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (size_t i = 0; i < included_list.GetSize(); ++i) {
427b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::string category;
428b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (!included_list.GetString(i, &category))
429b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      continue;
430b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
431b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                         TRACE_DISABLED_BY_DEFAULT("")) == 0) {
432b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      disabled_categories_.push_back(category);
433b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    } else {
434b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      included_categories_.push_back(category);
435b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
436b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
437b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
438b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
439b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::SetCategoriesFromExcludedList(
440b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const base::ListValue& excluded_list) {
441b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  excluded_categories_.clear();
442b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (size_t i = 0; i < excluded_list.GetSize(); ++i) {
443b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::string category;
444b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (excluded_list.GetString(i, &category))
445b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      excluded_categories_.push_back(category);
446b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
447b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
448b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
449b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::SetSyntheticDelaysFromList(const base::ListValue& list) {
450b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  synthetic_delays_.clear();
451b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (size_t i = 0; i < list.GetSize(); ++i) {
452b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    std::string delay;
453b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (!list.GetString(i, &delay))
454b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      continue;
455b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    // Synthetic delays are of the form "delay;option;option;...".
456b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    size_t name_length = delay.find(';');
457b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (name_length != std::string::npos && name_length > 0 &&
458b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat        name_length != delay.size() - 1) {
459b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      synthetic_delays_.push_back(delay);
460b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    }
461b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
462b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
463b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
464b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::AddCategoryToDict(base::DictionaryValue& dict,
465b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                    const char* param,
466b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                    const StringList& categories) const {
467b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (categories.empty())
468b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return;
469b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
470b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  scoped_ptr<base::ListValue> list(new base::ListValue());
471b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (StringList::const_iterator ci = categories.begin();
472b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ci != categories.end();
473b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ++ci) {
474b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    list->AppendString(*ci);
475b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
476b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
477cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  dict.Set(param, std::move(list));
478cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}
479cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
480cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkovoid TraceConfig::SetMemoryDumpConfig(
481cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const base::DictionaryValue& memory_dump_config) {
482cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.clear();
483cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
484cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  const base::ListValue* trigger_list = nullptr;
485cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  if (!memory_dump_config.GetList(kTriggersParam, &trigger_list) ||
486cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      trigger_list->GetSize() == 0) {
487cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    return;
488cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
489cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
490cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  for (size_t i = 0; i < trigger_list->GetSize(); ++i) {
491cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    const base::DictionaryValue* trigger = nullptr;
492cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!trigger_list->GetDictionary(i, &trigger))
493cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      continue;
494cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
495cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    MemoryDumpTriggerConfig dump_config;
496cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    int interval = 0;
497cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
498cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (!trigger->GetInteger(kPeriodicIntervalParam, &interval)) {
499cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      continue;
500cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
501cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    DCHECK_GT(interval, 0);
502cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    dump_config.periodic_interval_ms = static_cast<uint32_t>(interval);
503cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    std::string level_of_detail_str;
504cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    trigger->GetString(kModeParam, &level_of_detail_str);
505cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    dump_config.level_of_detail =
506cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        StringToMemoryDumpLevelOfDetail(level_of_detail_str);
507cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    memory_dump_config_.push_back(dump_config);
508cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
509cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko}
510cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
511cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkovoid TraceConfig::SetDefaultMemoryDumpConfig() {
512cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.clear();
513cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.push_back(kDefaultHeavyMemoryDumpTrigger);
514cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  memory_dump_config_.push_back(kDefaultLightMemoryDumpTrigger);
515b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
516b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
517b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::ToDict(base::DictionaryValue& dict) const {
518b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  switch (record_mode_) {
519b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_UNTIL_FULL:
520b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      dict.SetString(kRecordModeParam, kRecordUntilFull);
521b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
522b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_CONTINUOUSLY:
523b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      dict.SetString(kRecordModeParam, kRecordContinuously);
524b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
525b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_AS_MUCH_AS_POSSIBLE:
526b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      dict.SetString(kRecordModeParam, kRecordAsMuchAsPossible);
527b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
528b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case ECHO_TO_CONSOLE:
529b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      dict.SetString(kRecordModeParam, kTraceToConsole);
530b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
531b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    default:
532b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      NOTREACHED();
533b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
534b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
535b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_sampling_)
536b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableSamplingParam, true);
537b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
538b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableSamplingParam, false);
539b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
540b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_systrace_)
541b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableSystraceParam, true);
542b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
543b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableSystraceParam, false);
544b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
545b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_argument_filter_)
546b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableArgumentFilterParam, true);
547b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  else
548b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    dict.SetBoolean(kEnableArgumentFilterParam, false);
549b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
550b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  StringList categories(included_categories_);
551b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  categories.insert(categories.end(),
552b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                    disabled_categories_.begin(),
553b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                    disabled_categories_.end());
554b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  AddCategoryToDict(dict, kIncludedCategoriesParam, categories);
555b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_);
556b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_);
557cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
558cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
559cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    scoped_ptr<base::DictionaryValue> memory_dump_config(
560cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko        new base::DictionaryValue());
561cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    scoped_ptr<base::ListValue> triggers_list(new base::ListValue());
562cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    for (const MemoryDumpTriggerConfig& config : memory_dump_config_) {
563cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      scoped_ptr<base::DictionaryValue> trigger_dict(
564cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          new base::DictionaryValue());
565cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      trigger_dict->SetInteger(kPeriodicIntervalParam,
566cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                               static_cast<int>(config.periodic_interval_ms));
567cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      trigger_dict->SetString(
568cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko          kModeParam, MemoryDumpLevelOfDetailToString(config.level_of_detail));
569cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      triggers_list->Append(std::move(trigger_dict));
570cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    }
571cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
572cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    // Empty triggers will still be specified explicitly since it means that
573cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    // the periodic dumps are not enabled.
574cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    memory_dump_config->Set(kTriggersParam, std::move(triggers_list));
575cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    dict.Set(kMemoryDumpConfigParam, std::move(memory_dump_config));
576cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  }
577b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
578b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
579b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string TraceConfig::ToTraceOptionsString() const {
580b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  std::string ret;
581b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  switch (record_mode_) {
582b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_UNTIL_FULL:
583b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      ret = kRecordUntilFull;
584b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
585b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_CONTINUOUSLY:
586b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      ret = kRecordContinuously;
587b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
588b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case RECORD_AS_MUCH_AS_POSSIBLE:
589b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      ret = kRecordAsMuchAsPossible;
590b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
591b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case ECHO_TO_CONSOLE:
592b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      ret = kTraceToConsole;
593b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      break;
594b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    default:
595b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      NOTREACHED();
596b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
597b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_sampling_)
598b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ret = ret + "," + kEnableSampling;
599b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_systrace_)
600b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ret = ret + "," + kEnableSystrace;
601b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (enable_argument_filter_)
602b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ret = ret + "," + kEnableArgumentFilter;
603b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return ret;
604b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
605b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
606b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::WriteCategoryFilterString(const StringList& values,
607b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                            std::string* out,
608b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                            bool included) const {
609b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool prepend_comma = !out->empty();
610b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int token_cnt = 0;
611b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (StringList::const_iterator ci = values.begin();
612b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ci != values.end(); ++ci) {
613b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (token_cnt > 0 || prepend_comma)
614b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      StringAppendF(out, ",");
615b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str());
616b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ++token_cnt;
617b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
618b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
619b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
620b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid TraceConfig::WriteCategoryFilterString(const StringList& delays,
621b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                            std::string* out) const {
622b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool prepend_comma = !out->empty();
623b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  int token_cnt = 0;
624b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (StringList::const_iterator ci = delays.begin();
625b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ci != delays.end(); ++ci) {
626b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (token_cnt > 0 || prepend_comma)
627b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      StringAppendF(out, ",");
628b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    StringAppendF(out, "%s%s)", kSyntheticDelayCategoryFilterPrefix,
629b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                  ci->c_str());
630b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    ++token_cnt;
631b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
632b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
633b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
634b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool TraceConfig::IsCategoryEnabled(const char* category_name) const {
635b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  StringList::const_iterator ci;
636b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
637b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Check the disabled- filters and the disabled-* wildcard first so that a
638b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // "*" filter does not include the disabled.
639b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (ci = disabled_categories_.begin();
640b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ci != disabled_categories_.end();
641b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ++ci) {
642cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (base::MatchPattern(category_name, ci->c_str()))
643b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return true;
644b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
645b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
646cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  if (base::MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
647b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return false;
648b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
649b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  for (ci = included_categories_.begin();
650b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ci != included_categories_.end();
651b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat       ++ci) {
652cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (base::MatchPattern(category_name, ci->c_str()))
653b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return true;
654b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
655b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
656b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return false;
657b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
658b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
659b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool TraceConfig::IsEmptyOrContainsLeadingOrTrailingWhitespace(
660b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    const std::string& str) {
661b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return  str.empty() ||
662b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          str.at(0) == ' ' ||
663b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat          str.at(str.length() - 1) == ' ';
664b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
665b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
666b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool TraceConfig::HasIncludedPatterns() const {
667b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return !included_categories_.empty();
668b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
669b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
670b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace trace_event
671b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace base
672