xref: /aosp_15_r20/external/libchrome/base/trace_event/trace_config.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_config.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <utility>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_manager.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_request_args.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event.h"
18*635a8641SAndroid Build Coastguard Worker 
19*635a8641SAndroid Build Coastguard Worker namespace base {
20*635a8641SAndroid Build Coastguard Worker namespace trace_event {
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker namespace {
23*635a8641SAndroid Build Coastguard Worker 
24*635a8641SAndroid Build Coastguard Worker // String options that can be used to initialize TraceOptions.
25*635a8641SAndroid Build Coastguard Worker const char kRecordUntilFull[] = "record-until-full";
26*635a8641SAndroid Build Coastguard Worker const char kRecordContinuously[] = "record-continuously";
27*635a8641SAndroid Build Coastguard Worker const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible";
28*635a8641SAndroid Build Coastguard Worker const char kTraceToConsole[] = "trace-to-console";
29*635a8641SAndroid Build Coastguard Worker const char kEnableSystrace[] = "enable-systrace";
30*635a8641SAndroid Build Coastguard Worker const char kEnableArgumentFilter[] = "enable-argument-filter";
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker // String parameters that can be used to parse the trace config string.
33*635a8641SAndroid Build Coastguard Worker const char kRecordModeParam[] = "record_mode";
34*635a8641SAndroid Build Coastguard Worker const char kEnableSystraceParam[] = "enable_systrace";
35*635a8641SAndroid Build Coastguard Worker const char kEnableArgumentFilterParam[] = "enable_argument_filter";
36*635a8641SAndroid Build Coastguard Worker 
37*635a8641SAndroid Build Coastguard Worker // String parameters that is used to parse memory dump config in trace config
38*635a8641SAndroid Build Coastguard Worker // string.
39*635a8641SAndroid Build Coastguard Worker const char kMemoryDumpConfigParam[] = "memory_dump_config";
40*635a8641SAndroid Build Coastguard Worker const char kAllowedDumpModesParam[] = "allowed_dump_modes";
41*635a8641SAndroid Build Coastguard Worker const char kTriggersParam[] = "triggers";
42*635a8641SAndroid Build Coastguard Worker const char kTriggerModeParam[] = "mode";
43*635a8641SAndroid Build Coastguard Worker const char kMinTimeBetweenDumps[] = "min_time_between_dumps_ms";
44*635a8641SAndroid Build Coastguard Worker const char kTriggerTypeParam[] = "type";
45*635a8641SAndroid Build Coastguard Worker const char kPeriodicIntervalLegacyParam[] = "periodic_interval_ms";
46*635a8641SAndroid Build Coastguard Worker const char kHeapProfilerOptions[] = "heap_profiler_options";
47*635a8641SAndroid Build Coastguard Worker const char kBreakdownThresholdBytes[] = "breakdown_threshold_bytes";
48*635a8641SAndroid Build Coastguard Worker 
49*635a8641SAndroid Build Coastguard Worker // String parameters used to parse category event filters.
50*635a8641SAndroid Build Coastguard Worker const char kEventFiltersParam[] = "event_filters";
51*635a8641SAndroid Build Coastguard Worker const char kFilterPredicateParam[] = "filter_predicate";
52*635a8641SAndroid Build Coastguard Worker const char kFilterArgsParam[] = "filter_args";
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker // String parameter used to parse process filter.
55*635a8641SAndroid Build Coastguard Worker const char kIncludedProcessesParam[] = "included_process_ids";
56*635a8641SAndroid Build Coastguard Worker 
57*635a8641SAndroid Build Coastguard Worker class ConvertableTraceConfigToTraceFormat
58*635a8641SAndroid Build Coastguard Worker     : public base::trace_event::ConvertableToTraceFormat {
59*635a8641SAndroid Build Coastguard Worker  public:
ConvertableTraceConfigToTraceFormat(const TraceConfig & trace_config)60*635a8641SAndroid Build Coastguard Worker   explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config)
61*635a8641SAndroid Build Coastguard Worker       : trace_config_(trace_config) {}
62*635a8641SAndroid Build Coastguard Worker 
63*635a8641SAndroid Build Coastguard Worker   ~ConvertableTraceConfigToTraceFormat() override = default;
64*635a8641SAndroid Build Coastguard Worker 
AppendAsTraceFormat(std::string * out) const65*635a8641SAndroid Build Coastguard Worker   void AppendAsTraceFormat(std::string* out) const override {
66*635a8641SAndroid Build Coastguard Worker     out->append(trace_config_.ToString());
67*635a8641SAndroid Build Coastguard Worker   }
68*635a8641SAndroid Build Coastguard Worker 
69*635a8641SAndroid Build Coastguard Worker  private:
70*635a8641SAndroid Build Coastguard Worker   const TraceConfig trace_config_;
71*635a8641SAndroid Build Coastguard Worker };
72*635a8641SAndroid Build Coastguard Worker 
GetDefaultAllowedMemoryDumpModes()73*635a8641SAndroid Build Coastguard Worker std::set<MemoryDumpLevelOfDetail> GetDefaultAllowedMemoryDumpModes() {
74*635a8641SAndroid Build Coastguard Worker   std::set<MemoryDumpLevelOfDetail> all_modes;
75*635a8641SAndroid Build Coastguard Worker   for (uint32_t mode = static_cast<uint32_t>(MemoryDumpLevelOfDetail::FIRST);
76*635a8641SAndroid Build Coastguard Worker        mode <= static_cast<uint32_t>(MemoryDumpLevelOfDetail::LAST); mode++) {
77*635a8641SAndroid Build Coastguard Worker     all_modes.insert(static_cast<MemoryDumpLevelOfDetail>(mode));
78*635a8641SAndroid Build Coastguard Worker   }
79*635a8641SAndroid Build Coastguard Worker   return all_modes;
80*635a8641SAndroid Build Coastguard Worker }
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker }  // namespace
83*635a8641SAndroid Build Coastguard Worker 
HeapProfiler()84*635a8641SAndroid Build Coastguard Worker TraceConfig::MemoryDumpConfig::HeapProfiler::HeapProfiler()
85*635a8641SAndroid Build Coastguard Worker     : breakdown_threshold_bytes(kDefaultBreakdownThresholdBytes) {}
86*635a8641SAndroid Build Coastguard Worker 
Clear()87*635a8641SAndroid Build Coastguard Worker void TraceConfig::MemoryDumpConfig::HeapProfiler::Clear() {
88*635a8641SAndroid Build Coastguard Worker   breakdown_threshold_bytes = kDefaultBreakdownThresholdBytes;
89*635a8641SAndroid Build Coastguard Worker }
90*635a8641SAndroid Build Coastguard Worker 
ResetMemoryDumpConfig(const TraceConfig::MemoryDumpConfig & memory_dump_config)91*635a8641SAndroid Build Coastguard Worker void TraceConfig::ResetMemoryDumpConfig(
92*635a8641SAndroid Build Coastguard Worker     const TraceConfig::MemoryDumpConfig& memory_dump_config) {
93*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.Clear();
94*635a8641SAndroid Build Coastguard Worker   memory_dump_config_ = memory_dump_config;
95*635a8641SAndroid Build Coastguard Worker }
96*635a8641SAndroid Build Coastguard Worker 
97*635a8641SAndroid Build Coastguard Worker TraceConfig::MemoryDumpConfig::MemoryDumpConfig() = default;
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker TraceConfig::MemoryDumpConfig::MemoryDumpConfig(
100*635a8641SAndroid Build Coastguard Worker     const MemoryDumpConfig& other) = default;
101*635a8641SAndroid Build Coastguard Worker 
102*635a8641SAndroid Build Coastguard Worker TraceConfig::MemoryDumpConfig::~MemoryDumpConfig() = default;
103*635a8641SAndroid Build Coastguard Worker 
Clear()104*635a8641SAndroid Build Coastguard Worker void TraceConfig::MemoryDumpConfig::Clear() {
105*635a8641SAndroid Build Coastguard Worker   allowed_dump_modes.clear();
106*635a8641SAndroid Build Coastguard Worker   triggers.clear();
107*635a8641SAndroid Build Coastguard Worker   heap_profiler_options.Clear();
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker 
Merge(const TraceConfig::MemoryDumpConfig & config)110*635a8641SAndroid Build Coastguard Worker void TraceConfig::MemoryDumpConfig::Merge(
111*635a8641SAndroid Build Coastguard Worker     const TraceConfig::MemoryDumpConfig& config) {
112*635a8641SAndroid Build Coastguard Worker   triggers.insert(triggers.end(), config.triggers.begin(),
113*635a8641SAndroid Build Coastguard Worker                   config.triggers.end());
114*635a8641SAndroid Build Coastguard Worker   allowed_dump_modes.insert(config.allowed_dump_modes.begin(),
115*635a8641SAndroid Build Coastguard Worker                             config.allowed_dump_modes.end());
116*635a8641SAndroid Build Coastguard Worker   heap_profiler_options.breakdown_threshold_bytes =
117*635a8641SAndroid Build Coastguard Worker       std::min(heap_profiler_options.breakdown_threshold_bytes,
118*635a8641SAndroid Build Coastguard Worker                config.heap_profiler_options.breakdown_threshold_bytes);
119*635a8641SAndroid Build Coastguard Worker }
120*635a8641SAndroid Build Coastguard Worker 
121*635a8641SAndroid Build Coastguard Worker TraceConfig::ProcessFilterConfig::ProcessFilterConfig() = default;
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker TraceConfig::ProcessFilterConfig::ProcessFilterConfig(
124*635a8641SAndroid Build Coastguard Worker     const ProcessFilterConfig& other) = default;
125*635a8641SAndroid Build Coastguard Worker 
ProcessFilterConfig(const std::unordered_set<base::ProcessId> & included_process_ids)126*635a8641SAndroid Build Coastguard Worker TraceConfig::ProcessFilterConfig::ProcessFilterConfig(
127*635a8641SAndroid Build Coastguard Worker     const std::unordered_set<base::ProcessId>& included_process_ids)
128*635a8641SAndroid Build Coastguard Worker     : included_process_ids_(included_process_ids) {}
129*635a8641SAndroid Build Coastguard Worker 
130*635a8641SAndroid Build Coastguard Worker TraceConfig::ProcessFilterConfig::~ProcessFilterConfig() = default;
131*635a8641SAndroid Build Coastguard Worker 
Clear()132*635a8641SAndroid Build Coastguard Worker void TraceConfig::ProcessFilterConfig::Clear() {
133*635a8641SAndroid Build Coastguard Worker   included_process_ids_.clear();
134*635a8641SAndroid Build Coastguard Worker }
135*635a8641SAndroid Build Coastguard Worker 
Merge(const ProcessFilterConfig & config)136*635a8641SAndroid Build Coastguard Worker void TraceConfig::ProcessFilterConfig::Merge(
137*635a8641SAndroid Build Coastguard Worker     const ProcessFilterConfig& config) {
138*635a8641SAndroid Build Coastguard Worker   included_process_ids_.insert(config.included_process_ids_.begin(),
139*635a8641SAndroid Build Coastguard Worker                                config.included_process_ids_.end());
140*635a8641SAndroid Build Coastguard Worker }
141*635a8641SAndroid Build Coastguard Worker 
InitializeFromConfigDict(const base::DictionaryValue & dict)142*635a8641SAndroid Build Coastguard Worker void TraceConfig::ProcessFilterConfig::InitializeFromConfigDict(
143*635a8641SAndroid Build Coastguard Worker     const base::DictionaryValue& dict) {
144*635a8641SAndroid Build Coastguard Worker   included_process_ids_.clear();
145*635a8641SAndroid Build Coastguard Worker   const Value* value =
146*635a8641SAndroid Build Coastguard Worker       dict.FindKeyOfType(kIncludedProcessesParam, Value::Type::LIST);
147*635a8641SAndroid Build Coastguard Worker   if (!value)
148*635a8641SAndroid Build Coastguard Worker     return;
149*635a8641SAndroid Build Coastguard Worker   for (auto& pid_value : value->GetList()) {
150*635a8641SAndroid Build Coastguard Worker     if (pid_value.is_int())
151*635a8641SAndroid Build Coastguard Worker       included_process_ids_.insert(pid_value.GetInt());
152*635a8641SAndroid Build Coastguard Worker   }
153*635a8641SAndroid Build Coastguard Worker }
154*635a8641SAndroid Build Coastguard Worker 
ToDict(DictionaryValue * dict) const155*635a8641SAndroid Build Coastguard Worker void TraceConfig::ProcessFilterConfig::ToDict(DictionaryValue* dict) const {
156*635a8641SAndroid Build Coastguard Worker   if (included_process_ids_.empty())
157*635a8641SAndroid Build Coastguard Worker     return;
158*635a8641SAndroid Build Coastguard Worker   Value* list = dict->SetKey(kIncludedProcessesParam, Value(Value::Type::LIST));
159*635a8641SAndroid Build Coastguard Worker   std::set<base::ProcessId> ordered_set(included_process_ids_.begin(),
160*635a8641SAndroid Build Coastguard Worker                                         included_process_ids_.end());
161*635a8641SAndroid Build Coastguard Worker   for (auto process_id : ordered_set)
162*635a8641SAndroid Build Coastguard Worker     list->GetList().emplace_back(static_cast<int>(process_id));
163*635a8641SAndroid Build Coastguard Worker }
164*635a8641SAndroid Build Coastguard Worker 
IsEnabled(base::ProcessId process_id) const165*635a8641SAndroid Build Coastguard Worker bool TraceConfig::ProcessFilterConfig::IsEnabled(
166*635a8641SAndroid Build Coastguard Worker     base::ProcessId process_id) const {
167*635a8641SAndroid Build Coastguard Worker   return included_process_ids_.empty() ||
168*635a8641SAndroid Build Coastguard Worker          included_process_ids_.count(process_id);
169*635a8641SAndroid Build Coastguard Worker }
170*635a8641SAndroid Build Coastguard Worker 
EventFilterConfig(const std::string & predicate_name)171*635a8641SAndroid Build Coastguard Worker TraceConfig::EventFilterConfig::EventFilterConfig(
172*635a8641SAndroid Build Coastguard Worker     const std::string& predicate_name)
173*635a8641SAndroid Build Coastguard Worker     : predicate_name_(predicate_name) {}
174*635a8641SAndroid Build Coastguard Worker 
175*635a8641SAndroid Build Coastguard Worker TraceConfig::EventFilterConfig::~EventFilterConfig() = default;
176*635a8641SAndroid Build Coastguard Worker 
EventFilterConfig(const EventFilterConfig & tc)177*635a8641SAndroid Build Coastguard Worker TraceConfig::EventFilterConfig::EventFilterConfig(const EventFilterConfig& tc) {
178*635a8641SAndroid Build Coastguard Worker   *this = tc;
179*635a8641SAndroid Build Coastguard Worker }
180*635a8641SAndroid Build Coastguard Worker 
operator =(const TraceConfig::EventFilterConfig & rhs)181*635a8641SAndroid Build Coastguard Worker TraceConfig::EventFilterConfig& TraceConfig::EventFilterConfig::operator=(
182*635a8641SAndroid Build Coastguard Worker     const TraceConfig::EventFilterConfig& rhs) {
183*635a8641SAndroid Build Coastguard Worker   if (this == &rhs)
184*635a8641SAndroid Build Coastguard Worker     return *this;
185*635a8641SAndroid Build Coastguard Worker 
186*635a8641SAndroid Build Coastguard Worker   predicate_name_ = rhs.predicate_name_;
187*635a8641SAndroid Build Coastguard Worker   category_filter_ = rhs.category_filter_;
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   if (rhs.args_)
190*635a8641SAndroid Build Coastguard Worker     args_ = rhs.args_->CreateDeepCopy();
191*635a8641SAndroid Build Coastguard Worker 
192*635a8641SAndroid Build Coastguard Worker   return *this;
193*635a8641SAndroid Build Coastguard Worker }
194*635a8641SAndroid Build Coastguard Worker 
InitializeFromConfigDict(const base::DictionaryValue * event_filter)195*635a8641SAndroid Build Coastguard Worker void TraceConfig::EventFilterConfig::InitializeFromConfigDict(
196*635a8641SAndroid Build Coastguard Worker     const base::DictionaryValue* event_filter) {
197*635a8641SAndroid Build Coastguard Worker   category_filter_.InitializeFromConfigDict(*event_filter);
198*635a8641SAndroid Build Coastguard Worker 
199*635a8641SAndroid Build Coastguard Worker   const base::DictionaryValue* args_dict = nullptr;
200*635a8641SAndroid Build Coastguard Worker   if (event_filter->GetDictionary(kFilterArgsParam, &args_dict))
201*635a8641SAndroid Build Coastguard Worker     args_ = args_dict->CreateDeepCopy();
202*635a8641SAndroid Build Coastguard Worker }
203*635a8641SAndroid Build Coastguard Worker 
SetCategoryFilter(const TraceConfigCategoryFilter & category_filter)204*635a8641SAndroid Build Coastguard Worker void TraceConfig::EventFilterConfig::SetCategoryFilter(
205*635a8641SAndroid Build Coastguard Worker     const TraceConfigCategoryFilter& category_filter) {
206*635a8641SAndroid Build Coastguard Worker   category_filter_ = category_filter;
207*635a8641SAndroid Build Coastguard Worker }
208*635a8641SAndroid Build Coastguard Worker 
ToDict(DictionaryValue * filter_dict) const209*635a8641SAndroid Build Coastguard Worker void TraceConfig::EventFilterConfig::ToDict(
210*635a8641SAndroid Build Coastguard Worker     DictionaryValue* filter_dict) const {
211*635a8641SAndroid Build Coastguard Worker   filter_dict->SetString(kFilterPredicateParam, predicate_name());
212*635a8641SAndroid Build Coastguard Worker 
213*635a8641SAndroid Build Coastguard Worker   category_filter_.ToDict(filter_dict);
214*635a8641SAndroid Build Coastguard Worker 
215*635a8641SAndroid Build Coastguard Worker   if (args_)
216*635a8641SAndroid Build Coastguard Worker     filter_dict->Set(kFilterArgsParam, args_->CreateDeepCopy());
217*635a8641SAndroid Build Coastguard Worker }
218*635a8641SAndroid Build Coastguard Worker 
GetArgAsSet(const char * key,std::unordered_set<std::string> * out_set) const219*635a8641SAndroid Build Coastguard Worker bool TraceConfig::EventFilterConfig::GetArgAsSet(
220*635a8641SAndroid Build Coastguard Worker     const char* key,
221*635a8641SAndroid Build Coastguard Worker     std::unordered_set<std::string>* out_set) const {
222*635a8641SAndroid Build Coastguard Worker   const ListValue* list = nullptr;
223*635a8641SAndroid Build Coastguard Worker   if (!args_->GetList(key, &list))
224*635a8641SAndroid Build Coastguard Worker     return false;
225*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < list->GetSize(); ++i) {
226*635a8641SAndroid Build Coastguard Worker     std::string value;
227*635a8641SAndroid Build Coastguard Worker     if (list->GetString(i, &value))
228*635a8641SAndroid Build Coastguard Worker       out_set->insert(value);
229*635a8641SAndroid Build Coastguard Worker   }
230*635a8641SAndroid Build Coastguard Worker   return true;
231*635a8641SAndroid Build Coastguard Worker }
232*635a8641SAndroid Build Coastguard Worker 
IsCategoryGroupEnabled(const StringPiece & category_group_name) const233*635a8641SAndroid Build Coastguard Worker bool TraceConfig::EventFilterConfig::IsCategoryGroupEnabled(
234*635a8641SAndroid Build Coastguard Worker     const StringPiece& category_group_name) const {
235*635a8641SAndroid Build Coastguard Worker   return category_filter_.IsCategoryGroupEnabled(category_group_name);
236*635a8641SAndroid Build Coastguard Worker }
237*635a8641SAndroid Build Coastguard Worker 
238*635a8641SAndroid Build Coastguard Worker // static
TraceRecordModeToStr(TraceRecordMode record_mode)239*635a8641SAndroid Build Coastguard Worker std::string TraceConfig::TraceRecordModeToStr(TraceRecordMode record_mode) {
240*635a8641SAndroid Build Coastguard Worker   switch (record_mode) {
241*635a8641SAndroid Build Coastguard Worker     case RECORD_UNTIL_FULL:
242*635a8641SAndroid Build Coastguard Worker       return kRecordUntilFull;
243*635a8641SAndroid Build Coastguard Worker     case RECORD_CONTINUOUSLY:
244*635a8641SAndroid Build Coastguard Worker       return kRecordContinuously;
245*635a8641SAndroid Build Coastguard Worker     case RECORD_AS_MUCH_AS_POSSIBLE:
246*635a8641SAndroid Build Coastguard Worker       return kRecordAsMuchAsPossible;
247*635a8641SAndroid Build Coastguard Worker     case ECHO_TO_CONSOLE:
248*635a8641SAndroid Build Coastguard Worker       return kTraceToConsole;
249*635a8641SAndroid Build Coastguard Worker     default:
250*635a8641SAndroid Build Coastguard Worker       NOTREACHED();
251*635a8641SAndroid Build Coastguard Worker   }
252*635a8641SAndroid Build Coastguard Worker   return kRecordUntilFull;
253*635a8641SAndroid Build Coastguard Worker }
254*635a8641SAndroid Build Coastguard Worker 
TraceConfig()255*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig() {
256*635a8641SAndroid Build Coastguard Worker   InitializeDefault();
257*635a8641SAndroid Build Coastguard Worker }
258*635a8641SAndroid Build Coastguard Worker 
TraceConfig(StringPiece category_filter_string,StringPiece trace_options_string)259*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig(StringPiece category_filter_string,
260*635a8641SAndroid Build Coastguard Worker                          StringPiece trace_options_string) {
261*635a8641SAndroid Build Coastguard Worker   InitializeFromStrings(category_filter_string, trace_options_string);
262*635a8641SAndroid Build Coastguard Worker }
263*635a8641SAndroid Build Coastguard Worker 
TraceConfig(StringPiece category_filter_string,TraceRecordMode record_mode)264*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig(StringPiece category_filter_string,
265*635a8641SAndroid Build Coastguard Worker                          TraceRecordMode record_mode) {
266*635a8641SAndroid Build Coastguard Worker   InitializeFromStrings(category_filter_string,
267*635a8641SAndroid Build Coastguard Worker                         TraceConfig::TraceRecordModeToStr(record_mode));
268*635a8641SAndroid Build Coastguard Worker }
269*635a8641SAndroid Build Coastguard Worker 
TraceConfig(const DictionaryValue & config)270*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig(const DictionaryValue& config) {
271*635a8641SAndroid Build Coastguard Worker   InitializeFromConfigDict(config);
272*635a8641SAndroid Build Coastguard Worker }
273*635a8641SAndroid Build Coastguard Worker 
TraceConfig(StringPiece config_string)274*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig(StringPiece config_string) {
275*635a8641SAndroid Build Coastguard Worker   if (!config_string.empty())
276*635a8641SAndroid Build Coastguard Worker     InitializeFromConfigString(config_string);
277*635a8641SAndroid Build Coastguard Worker   else
278*635a8641SAndroid Build Coastguard Worker     InitializeDefault();
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker 
281*635a8641SAndroid Build Coastguard Worker TraceConfig::TraceConfig(const TraceConfig& tc) = default;
282*635a8641SAndroid Build Coastguard Worker 
283*635a8641SAndroid Build Coastguard Worker TraceConfig::~TraceConfig() = default;
284*635a8641SAndroid Build Coastguard Worker 
operator =(const TraceConfig & rhs)285*635a8641SAndroid Build Coastguard Worker TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) {
286*635a8641SAndroid Build Coastguard Worker   if (this == &rhs)
287*635a8641SAndroid Build Coastguard Worker     return *this;
288*635a8641SAndroid Build Coastguard Worker 
289*635a8641SAndroid Build Coastguard Worker   record_mode_ = rhs.record_mode_;
290*635a8641SAndroid Build Coastguard Worker   enable_systrace_ = rhs.enable_systrace_;
291*635a8641SAndroid Build Coastguard Worker   enable_argument_filter_ = rhs.enable_argument_filter_;
292*635a8641SAndroid Build Coastguard Worker   category_filter_ = rhs.category_filter_;
293*635a8641SAndroid Build Coastguard Worker   process_filter_config_ = rhs.process_filter_config_;
294*635a8641SAndroid Build Coastguard Worker   memory_dump_config_ = rhs.memory_dump_config_;
295*635a8641SAndroid Build Coastguard Worker   event_filters_ = rhs.event_filters_;
296*635a8641SAndroid Build Coastguard Worker   return *this;
297*635a8641SAndroid Build Coastguard Worker }
298*635a8641SAndroid Build Coastguard Worker 
ToString() const299*635a8641SAndroid Build Coastguard Worker std::string TraceConfig::ToString() const {
300*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<DictionaryValue> dict = ToDict();
301*635a8641SAndroid Build Coastguard Worker   std::string json;
302*635a8641SAndroid Build Coastguard Worker   JSONWriter::Write(*dict, &json);
303*635a8641SAndroid Build Coastguard Worker   return json;
304*635a8641SAndroid Build Coastguard Worker }
305*635a8641SAndroid Build Coastguard Worker 
306*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>
AsConvertableToTraceFormat() const307*635a8641SAndroid Build Coastguard Worker TraceConfig::AsConvertableToTraceFormat() const {
308*635a8641SAndroid Build Coastguard Worker   return std::make_unique<ConvertableTraceConfigToTraceFormat>(*this);
309*635a8641SAndroid Build Coastguard Worker }
310*635a8641SAndroid Build Coastguard Worker 
ToCategoryFilterString() const311*635a8641SAndroid Build Coastguard Worker std::string TraceConfig::ToCategoryFilterString() const {
312*635a8641SAndroid Build Coastguard Worker   return category_filter_.ToFilterString();
313*635a8641SAndroid Build Coastguard Worker }
314*635a8641SAndroid Build Coastguard Worker 
IsCategoryGroupEnabled(const StringPiece & category_group_name) const315*635a8641SAndroid Build Coastguard Worker bool TraceConfig::IsCategoryGroupEnabled(
316*635a8641SAndroid Build Coastguard Worker     const StringPiece& category_group_name) const {
317*635a8641SAndroid Build Coastguard Worker   // TraceLog should call this method only as part of enabling/disabling
318*635a8641SAndroid Build Coastguard Worker   // categories.
319*635a8641SAndroid Build Coastguard Worker   return category_filter_.IsCategoryGroupEnabled(category_group_name);
320*635a8641SAndroid Build Coastguard Worker }
321*635a8641SAndroid Build Coastguard Worker 
Merge(const TraceConfig & config)322*635a8641SAndroid Build Coastguard Worker void TraceConfig::Merge(const TraceConfig& config) {
323*635a8641SAndroid Build Coastguard Worker   if (record_mode_ != config.record_mode_
324*635a8641SAndroid Build Coastguard Worker       || enable_systrace_ != config.enable_systrace_
325*635a8641SAndroid Build Coastguard Worker       || enable_argument_filter_ != config.enable_argument_filter_) {
326*635a8641SAndroid Build Coastguard Worker     DLOG(ERROR) << "Attempting to merge trace config with a different "
327*635a8641SAndroid Build Coastguard Worker                 << "set of options.";
328*635a8641SAndroid Build Coastguard Worker   }
329*635a8641SAndroid Build Coastguard Worker 
330*635a8641SAndroid Build Coastguard Worker   category_filter_.Merge(config.category_filter_);
331*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.Merge(config.memory_dump_config_);
332*635a8641SAndroid Build Coastguard Worker   process_filter_config_.Merge(config.process_filter_config_);
333*635a8641SAndroid Build Coastguard Worker 
334*635a8641SAndroid Build Coastguard Worker   event_filters_.insert(event_filters_.end(), config.event_filters().begin(),
335*635a8641SAndroid Build Coastguard Worker                         config.event_filters().end());
336*635a8641SAndroid Build Coastguard Worker }
337*635a8641SAndroid Build Coastguard Worker 
Clear()338*635a8641SAndroid Build Coastguard Worker void TraceConfig::Clear() {
339*635a8641SAndroid Build Coastguard Worker   record_mode_ = RECORD_UNTIL_FULL;
340*635a8641SAndroid Build Coastguard Worker   enable_systrace_ = false;
341*635a8641SAndroid Build Coastguard Worker   enable_argument_filter_ = false;
342*635a8641SAndroid Build Coastguard Worker   category_filter_.Clear();
343*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.Clear();
344*635a8641SAndroid Build Coastguard Worker   process_filter_config_.Clear();
345*635a8641SAndroid Build Coastguard Worker   event_filters_.clear();
346*635a8641SAndroid Build Coastguard Worker }
347*635a8641SAndroid Build Coastguard Worker 
InitializeDefault()348*635a8641SAndroid Build Coastguard Worker void TraceConfig::InitializeDefault() {
349*635a8641SAndroid Build Coastguard Worker   record_mode_ = RECORD_UNTIL_FULL;
350*635a8641SAndroid Build Coastguard Worker   enable_systrace_ = false;
351*635a8641SAndroid Build Coastguard Worker   enable_argument_filter_ = false;
352*635a8641SAndroid Build Coastguard Worker }
353*635a8641SAndroid Build Coastguard Worker 
InitializeFromConfigDict(const DictionaryValue & dict)354*635a8641SAndroid Build Coastguard Worker void TraceConfig::InitializeFromConfigDict(const DictionaryValue& dict) {
355*635a8641SAndroid Build Coastguard Worker   record_mode_ = RECORD_UNTIL_FULL;
356*635a8641SAndroid Build Coastguard Worker   std::string record_mode;
357*635a8641SAndroid Build Coastguard Worker   if (dict.GetString(kRecordModeParam, &record_mode)) {
358*635a8641SAndroid Build Coastguard Worker     if (record_mode == kRecordUntilFull) {
359*635a8641SAndroid Build Coastguard Worker       record_mode_ = RECORD_UNTIL_FULL;
360*635a8641SAndroid Build Coastguard Worker     } else if (record_mode == kRecordContinuously) {
361*635a8641SAndroid Build Coastguard Worker       record_mode_ = RECORD_CONTINUOUSLY;
362*635a8641SAndroid Build Coastguard Worker     } else if (record_mode == kTraceToConsole) {
363*635a8641SAndroid Build Coastguard Worker       record_mode_ = ECHO_TO_CONSOLE;
364*635a8641SAndroid Build Coastguard Worker     } else if (record_mode == kRecordAsMuchAsPossible) {
365*635a8641SAndroid Build Coastguard Worker       record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
366*635a8641SAndroid Build Coastguard Worker     }
367*635a8641SAndroid Build Coastguard Worker   }
368*635a8641SAndroid Build Coastguard Worker 
369*635a8641SAndroid Build Coastguard Worker   bool val;
370*635a8641SAndroid Build Coastguard Worker   enable_systrace_ = dict.GetBoolean(kEnableSystraceParam, &val) ? val : false;
371*635a8641SAndroid Build Coastguard Worker   enable_argument_filter_ =
372*635a8641SAndroid Build Coastguard Worker       dict.GetBoolean(kEnableArgumentFilterParam, &val) ? val : false;
373*635a8641SAndroid Build Coastguard Worker 
374*635a8641SAndroid Build Coastguard Worker   category_filter_.InitializeFromConfigDict(dict);
375*635a8641SAndroid Build Coastguard Worker   process_filter_config_.InitializeFromConfigDict(dict);
376*635a8641SAndroid Build Coastguard Worker 
377*635a8641SAndroid Build Coastguard Worker   const base::ListValue* category_event_filters = nullptr;
378*635a8641SAndroid Build Coastguard Worker   if (dict.GetList(kEventFiltersParam, &category_event_filters))
379*635a8641SAndroid Build Coastguard Worker     SetEventFiltersFromConfigList(*category_event_filters);
380*635a8641SAndroid Build Coastguard Worker 
381*635a8641SAndroid Build Coastguard Worker   if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
382*635a8641SAndroid Build Coastguard Worker     // If dump triggers not set, the client is using the legacy with just
383*635a8641SAndroid Build Coastguard Worker     // category enabled. So, use the default periodic dump config.
384*635a8641SAndroid Build Coastguard Worker     const DictionaryValue* memory_dump_config = nullptr;
385*635a8641SAndroid Build Coastguard Worker     if (dict.GetDictionary(kMemoryDumpConfigParam, &memory_dump_config))
386*635a8641SAndroid Build Coastguard Worker       SetMemoryDumpConfigFromConfigDict(*memory_dump_config);
387*635a8641SAndroid Build Coastguard Worker     else
388*635a8641SAndroid Build Coastguard Worker       SetDefaultMemoryDumpConfig();
389*635a8641SAndroid Build Coastguard Worker   }
390*635a8641SAndroid Build Coastguard Worker }
391*635a8641SAndroid Build Coastguard Worker 
InitializeFromConfigString(StringPiece config_string)392*635a8641SAndroid Build Coastguard Worker void TraceConfig::InitializeFromConfigString(StringPiece config_string) {
393*635a8641SAndroid Build Coastguard Worker   auto dict = DictionaryValue::From(JSONReader::Read(config_string));
394*635a8641SAndroid Build Coastguard Worker   if (dict)
395*635a8641SAndroid Build Coastguard Worker     InitializeFromConfigDict(*dict);
396*635a8641SAndroid Build Coastguard Worker   else
397*635a8641SAndroid Build Coastguard Worker     InitializeDefault();
398*635a8641SAndroid Build Coastguard Worker }
399*635a8641SAndroid Build Coastguard Worker 
InitializeFromStrings(StringPiece category_filter_string,StringPiece trace_options_string)400*635a8641SAndroid Build Coastguard Worker void TraceConfig::InitializeFromStrings(StringPiece category_filter_string,
401*635a8641SAndroid Build Coastguard Worker                                         StringPiece trace_options_string) {
402*635a8641SAndroid Build Coastguard Worker   if (!category_filter_string.empty())
403*635a8641SAndroid Build Coastguard Worker     category_filter_.InitializeFromString(category_filter_string);
404*635a8641SAndroid Build Coastguard Worker 
405*635a8641SAndroid Build Coastguard Worker   record_mode_ = RECORD_UNTIL_FULL;
406*635a8641SAndroid Build Coastguard Worker   enable_systrace_ = false;
407*635a8641SAndroid Build Coastguard Worker   enable_argument_filter_ = false;
408*635a8641SAndroid Build Coastguard Worker   if (!trace_options_string.empty()) {
409*635a8641SAndroid Build Coastguard Worker     std::vector<std::string> split =
410*635a8641SAndroid Build Coastguard Worker         SplitString(trace_options_string, ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
411*635a8641SAndroid Build Coastguard Worker     for (const std::string& token : split) {
412*635a8641SAndroid Build Coastguard Worker       if (token == kRecordUntilFull) {
413*635a8641SAndroid Build Coastguard Worker         record_mode_ = RECORD_UNTIL_FULL;
414*635a8641SAndroid Build Coastguard Worker       } else if (token == kRecordContinuously) {
415*635a8641SAndroid Build Coastguard Worker         record_mode_ = RECORD_CONTINUOUSLY;
416*635a8641SAndroid Build Coastguard Worker       } else if (token == kTraceToConsole) {
417*635a8641SAndroid Build Coastguard Worker         record_mode_ = ECHO_TO_CONSOLE;
418*635a8641SAndroid Build Coastguard Worker       } else if (token == kRecordAsMuchAsPossible) {
419*635a8641SAndroid Build Coastguard Worker         record_mode_ = RECORD_AS_MUCH_AS_POSSIBLE;
420*635a8641SAndroid Build Coastguard Worker       } else if (token == kEnableSystrace) {
421*635a8641SAndroid Build Coastguard Worker         enable_systrace_ = true;
422*635a8641SAndroid Build Coastguard Worker       } else if (token == kEnableArgumentFilter) {
423*635a8641SAndroid Build Coastguard Worker         enable_argument_filter_ = true;
424*635a8641SAndroid Build Coastguard Worker       }
425*635a8641SAndroid Build Coastguard Worker     }
426*635a8641SAndroid Build Coastguard Worker   }
427*635a8641SAndroid Build Coastguard Worker 
428*635a8641SAndroid Build Coastguard Worker   if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
429*635a8641SAndroid Build Coastguard Worker     SetDefaultMemoryDumpConfig();
430*635a8641SAndroid Build Coastguard Worker   }
431*635a8641SAndroid Build Coastguard Worker }
432*635a8641SAndroid Build Coastguard Worker 
SetMemoryDumpConfigFromConfigDict(const DictionaryValue & memory_dump_config)433*635a8641SAndroid Build Coastguard Worker void TraceConfig::SetMemoryDumpConfigFromConfigDict(
434*635a8641SAndroid Build Coastguard Worker     const DictionaryValue& memory_dump_config) {
435*635a8641SAndroid Build Coastguard Worker   // Set allowed dump modes.
436*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.allowed_dump_modes.clear();
437*635a8641SAndroid Build Coastguard Worker   const ListValue* allowed_modes_list;
438*635a8641SAndroid Build Coastguard Worker   if (memory_dump_config.GetList(kAllowedDumpModesParam, &allowed_modes_list)) {
439*635a8641SAndroid Build Coastguard Worker     for (size_t i = 0; i < allowed_modes_list->GetSize(); ++i) {
440*635a8641SAndroid Build Coastguard Worker       std::string level_of_detail_str;
441*635a8641SAndroid Build Coastguard Worker       allowed_modes_list->GetString(i, &level_of_detail_str);
442*635a8641SAndroid Build Coastguard Worker       memory_dump_config_.allowed_dump_modes.insert(
443*635a8641SAndroid Build Coastguard Worker           StringToMemoryDumpLevelOfDetail(level_of_detail_str));
444*635a8641SAndroid Build Coastguard Worker     }
445*635a8641SAndroid Build Coastguard Worker   } else {
446*635a8641SAndroid Build Coastguard Worker     // If allowed modes param is not given then allow all modes by default.
447*635a8641SAndroid Build Coastguard Worker     memory_dump_config_.allowed_dump_modes = GetDefaultAllowedMemoryDumpModes();
448*635a8641SAndroid Build Coastguard Worker   }
449*635a8641SAndroid Build Coastguard Worker 
450*635a8641SAndroid Build Coastguard Worker   // Set triggers
451*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.triggers.clear();
452*635a8641SAndroid Build Coastguard Worker   const ListValue* trigger_list = nullptr;
453*635a8641SAndroid Build Coastguard Worker   if (memory_dump_config.GetList(kTriggersParam, &trigger_list) &&
454*635a8641SAndroid Build Coastguard Worker       trigger_list->GetSize() > 0) {
455*635a8641SAndroid Build Coastguard Worker     for (size_t i = 0; i < trigger_list->GetSize(); ++i) {
456*635a8641SAndroid Build Coastguard Worker       const DictionaryValue* trigger = nullptr;
457*635a8641SAndroid Build Coastguard Worker       if (!trigger_list->GetDictionary(i, &trigger))
458*635a8641SAndroid Build Coastguard Worker         continue;
459*635a8641SAndroid Build Coastguard Worker 
460*635a8641SAndroid Build Coastguard Worker       MemoryDumpConfig::Trigger dump_config;
461*635a8641SAndroid Build Coastguard Worker       int interval = 0;
462*635a8641SAndroid Build Coastguard Worker       if (!trigger->GetInteger(kMinTimeBetweenDumps, &interval)) {
463*635a8641SAndroid Build Coastguard Worker         // If "min_time_between_dumps_ms" param was not given, then the trace
464*635a8641SAndroid Build Coastguard Worker         // config uses old format where only periodic dumps are supported.
465*635a8641SAndroid Build Coastguard Worker         trigger->GetInteger(kPeriodicIntervalLegacyParam, &interval);
466*635a8641SAndroid Build Coastguard Worker         dump_config.trigger_type = MemoryDumpType::PERIODIC_INTERVAL;
467*635a8641SAndroid Build Coastguard Worker       } else {
468*635a8641SAndroid Build Coastguard Worker         std::string trigger_type_str;
469*635a8641SAndroid Build Coastguard Worker         trigger->GetString(kTriggerTypeParam, &trigger_type_str);
470*635a8641SAndroid Build Coastguard Worker         dump_config.trigger_type = StringToMemoryDumpType(trigger_type_str);
471*635a8641SAndroid Build Coastguard Worker       }
472*635a8641SAndroid Build Coastguard Worker       DCHECK_GT(interval, 0);
473*635a8641SAndroid Build Coastguard Worker       dump_config.min_time_between_dumps_ms = static_cast<uint32_t>(interval);
474*635a8641SAndroid Build Coastguard Worker 
475*635a8641SAndroid Build Coastguard Worker       std::string level_of_detail_str;
476*635a8641SAndroid Build Coastguard Worker       trigger->GetString(kTriggerModeParam, &level_of_detail_str);
477*635a8641SAndroid Build Coastguard Worker       dump_config.level_of_detail =
478*635a8641SAndroid Build Coastguard Worker           StringToMemoryDumpLevelOfDetail(level_of_detail_str);
479*635a8641SAndroid Build Coastguard Worker 
480*635a8641SAndroid Build Coastguard Worker       memory_dump_config_.triggers.push_back(dump_config);
481*635a8641SAndroid Build Coastguard Worker     }
482*635a8641SAndroid Build Coastguard Worker   }
483*635a8641SAndroid Build Coastguard Worker 
484*635a8641SAndroid Build Coastguard Worker   // Set heap profiler options
485*635a8641SAndroid Build Coastguard Worker   const DictionaryValue* heap_profiler_options = nullptr;
486*635a8641SAndroid Build Coastguard Worker   if (memory_dump_config.GetDictionary(kHeapProfilerOptions,
487*635a8641SAndroid Build Coastguard Worker                                        &heap_profiler_options)) {
488*635a8641SAndroid Build Coastguard Worker     int min_size_bytes = 0;
489*635a8641SAndroid Build Coastguard Worker     if (heap_profiler_options->GetInteger(kBreakdownThresholdBytes,
490*635a8641SAndroid Build Coastguard Worker                                          &min_size_bytes)
491*635a8641SAndroid Build Coastguard Worker         && min_size_bytes >= 0) {
492*635a8641SAndroid Build Coastguard Worker       memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes =
493*635a8641SAndroid Build Coastguard Worker           static_cast<size_t>(min_size_bytes);
494*635a8641SAndroid Build Coastguard Worker     } else {
495*635a8641SAndroid Build Coastguard Worker       memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes =
496*635a8641SAndroid Build Coastguard Worker           MemoryDumpConfig::HeapProfiler::kDefaultBreakdownThresholdBytes;
497*635a8641SAndroid Build Coastguard Worker     }
498*635a8641SAndroid Build Coastguard Worker   }
499*635a8641SAndroid Build Coastguard Worker }
500*635a8641SAndroid Build Coastguard Worker 
SetDefaultMemoryDumpConfig()501*635a8641SAndroid Build Coastguard Worker void TraceConfig::SetDefaultMemoryDumpConfig() {
502*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.Clear();
503*635a8641SAndroid Build Coastguard Worker   memory_dump_config_.allowed_dump_modes = GetDefaultAllowedMemoryDumpModes();
504*635a8641SAndroid Build Coastguard Worker }
505*635a8641SAndroid Build Coastguard Worker 
SetProcessFilterConfig(const ProcessFilterConfig & config)506*635a8641SAndroid Build Coastguard Worker void TraceConfig::SetProcessFilterConfig(const ProcessFilterConfig& config) {
507*635a8641SAndroid Build Coastguard Worker   process_filter_config_ = config;
508*635a8641SAndroid Build Coastguard Worker }
509*635a8641SAndroid Build Coastguard Worker 
SetEventFiltersFromConfigList(const base::ListValue & category_event_filters)510*635a8641SAndroid Build Coastguard Worker void TraceConfig::SetEventFiltersFromConfigList(
511*635a8641SAndroid Build Coastguard Worker     const base::ListValue& category_event_filters) {
512*635a8641SAndroid Build Coastguard Worker   event_filters_.clear();
513*635a8641SAndroid Build Coastguard Worker 
514*635a8641SAndroid Build Coastguard Worker   for (size_t event_filter_index = 0;
515*635a8641SAndroid Build Coastguard Worker        event_filter_index < category_event_filters.GetSize();
516*635a8641SAndroid Build Coastguard Worker        ++event_filter_index) {
517*635a8641SAndroid Build Coastguard Worker     const base::DictionaryValue* event_filter = nullptr;
518*635a8641SAndroid Build Coastguard Worker     if (!category_event_filters.GetDictionary(event_filter_index,
519*635a8641SAndroid Build Coastguard Worker                                               &event_filter))
520*635a8641SAndroid Build Coastguard Worker       continue;
521*635a8641SAndroid Build Coastguard Worker 
522*635a8641SAndroid Build Coastguard Worker     std::string predicate_name;
523*635a8641SAndroid Build Coastguard Worker     CHECK(event_filter->GetString(kFilterPredicateParam, &predicate_name))
524*635a8641SAndroid Build Coastguard Worker         << "Invalid predicate name in category event filter.";
525*635a8641SAndroid Build Coastguard Worker 
526*635a8641SAndroid Build Coastguard Worker     EventFilterConfig new_config(predicate_name);
527*635a8641SAndroid Build Coastguard Worker     new_config.InitializeFromConfigDict(event_filter);
528*635a8641SAndroid Build Coastguard Worker     event_filters_.push_back(new_config);
529*635a8641SAndroid Build Coastguard Worker   }
530*635a8641SAndroid Build Coastguard Worker }
531*635a8641SAndroid Build Coastguard Worker 
ToDict() const532*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> TraceConfig::ToDict() const {
533*635a8641SAndroid Build Coastguard Worker   auto dict = std::make_unique<DictionaryValue>();
534*635a8641SAndroid Build Coastguard Worker   dict->SetString(kRecordModeParam,
535*635a8641SAndroid Build Coastguard Worker                   TraceConfig::TraceRecordModeToStr(record_mode_));
536*635a8641SAndroid Build Coastguard Worker   dict->SetBoolean(kEnableSystraceParam, enable_systrace_);
537*635a8641SAndroid Build Coastguard Worker   dict->SetBoolean(kEnableArgumentFilterParam, enable_argument_filter_);
538*635a8641SAndroid Build Coastguard Worker 
539*635a8641SAndroid Build Coastguard Worker   category_filter_.ToDict(dict.get());
540*635a8641SAndroid Build Coastguard Worker   process_filter_config_.ToDict(dict.get());
541*635a8641SAndroid Build Coastguard Worker 
542*635a8641SAndroid Build Coastguard Worker   if (!event_filters_.empty()) {
543*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<base::ListValue> filter_list(new base::ListValue());
544*635a8641SAndroid Build Coastguard Worker     for (const EventFilterConfig& filter : event_filters_) {
545*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<base::DictionaryValue> filter_dict(
546*635a8641SAndroid Build Coastguard Worker           new base::DictionaryValue());
547*635a8641SAndroid Build Coastguard Worker       filter.ToDict(filter_dict.get());
548*635a8641SAndroid Build Coastguard Worker       filter_list->Append(std::move(filter_dict));
549*635a8641SAndroid Build Coastguard Worker     }
550*635a8641SAndroid Build Coastguard Worker     dict->Set(kEventFiltersParam, std::move(filter_list));
551*635a8641SAndroid Build Coastguard Worker   }
552*635a8641SAndroid Build Coastguard Worker 
553*635a8641SAndroid Build Coastguard Worker   if (category_filter_.IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) {
554*635a8641SAndroid Build Coastguard Worker     auto allowed_modes = std::make_unique<ListValue>();
555*635a8641SAndroid Build Coastguard Worker     for (auto dump_mode : memory_dump_config_.allowed_dump_modes)
556*635a8641SAndroid Build Coastguard Worker       allowed_modes->AppendString(MemoryDumpLevelOfDetailToString(dump_mode));
557*635a8641SAndroid Build Coastguard Worker 
558*635a8641SAndroid Build Coastguard Worker     auto memory_dump_config = std::make_unique<DictionaryValue>();
559*635a8641SAndroid Build Coastguard Worker     memory_dump_config->Set(kAllowedDumpModesParam, std::move(allowed_modes));
560*635a8641SAndroid Build Coastguard Worker 
561*635a8641SAndroid Build Coastguard Worker     auto triggers_list = std::make_unique<ListValue>();
562*635a8641SAndroid Build Coastguard Worker     for (const auto& config : memory_dump_config_.triggers) {
563*635a8641SAndroid Build Coastguard Worker       auto trigger_dict = std::make_unique<DictionaryValue>();
564*635a8641SAndroid Build Coastguard Worker       trigger_dict->SetString(kTriggerTypeParam,
565*635a8641SAndroid Build Coastguard Worker                               MemoryDumpTypeToString(config.trigger_type));
566*635a8641SAndroid Build Coastguard Worker       trigger_dict->SetInteger(
567*635a8641SAndroid Build Coastguard Worker           kMinTimeBetweenDumps,
568*635a8641SAndroid Build Coastguard Worker           static_cast<int>(config.min_time_between_dumps_ms));
569*635a8641SAndroid Build Coastguard Worker       trigger_dict->SetString(
570*635a8641SAndroid Build Coastguard Worker           kTriggerModeParam,
571*635a8641SAndroid Build Coastguard Worker           MemoryDumpLevelOfDetailToString(config.level_of_detail));
572*635a8641SAndroid Build Coastguard Worker       triggers_list->Append(std::move(trigger_dict));
573*635a8641SAndroid Build Coastguard Worker     }
574*635a8641SAndroid Build Coastguard Worker 
575*635a8641SAndroid Build Coastguard Worker     // Empty triggers will still be specified explicitly since it means that
576*635a8641SAndroid Build Coastguard Worker     // the periodic dumps are not enabled.
577*635a8641SAndroid Build Coastguard Worker     memory_dump_config->Set(kTriggersParam, std::move(triggers_list));
578*635a8641SAndroid Build Coastguard Worker 
579*635a8641SAndroid Build Coastguard Worker     if (memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes !=
580*635a8641SAndroid Build Coastguard Worker         MemoryDumpConfig::HeapProfiler::kDefaultBreakdownThresholdBytes) {
581*635a8641SAndroid Build Coastguard Worker       auto options = std::make_unique<DictionaryValue>();
582*635a8641SAndroid Build Coastguard Worker       options->SetInteger(
583*635a8641SAndroid Build Coastguard Worker           kBreakdownThresholdBytes,
584*635a8641SAndroid Build Coastguard Worker           memory_dump_config_.heap_profiler_options.breakdown_threshold_bytes);
585*635a8641SAndroid Build Coastguard Worker       memory_dump_config->Set(kHeapProfilerOptions, std::move(options));
586*635a8641SAndroid Build Coastguard Worker     }
587*635a8641SAndroid Build Coastguard Worker     dict->Set(kMemoryDumpConfigParam, std::move(memory_dump_config));
588*635a8641SAndroid Build Coastguard Worker   }
589*635a8641SAndroid Build Coastguard Worker   return dict;
590*635a8641SAndroid Build Coastguard Worker }
591*635a8641SAndroid Build Coastguard Worker 
ToTraceOptionsString() const592*635a8641SAndroid Build Coastguard Worker std::string TraceConfig::ToTraceOptionsString() const {
593*635a8641SAndroid Build Coastguard Worker   std::string ret;
594*635a8641SAndroid Build Coastguard Worker   switch (record_mode_) {
595*635a8641SAndroid Build Coastguard Worker     case RECORD_UNTIL_FULL:
596*635a8641SAndroid Build Coastguard Worker       ret = kRecordUntilFull;
597*635a8641SAndroid Build Coastguard Worker       break;
598*635a8641SAndroid Build Coastguard Worker     case RECORD_CONTINUOUSLY:
599*635a8641SAndroid Build Coastguard Worker       ret = kRecordContinuously;
600*635a8641SAndroid Build Coastguard Worker       break;
601*635a8641SAndroid Build Coastguard Worker     case RECORD_AS_MUCH_AS_POSSIBLE:
602*635a8641SAndroid Build Coastguard Worker       ret = kRecordAsMuchAsPossible;
603*635a8641SAndroid Build Coastguard Worker       break;
604*635a8641SAndroid Build Coastguard Worker     case ECHO_TO_CONSOLE:
605*635a8641SAndroid Build Coastguard Worker       ret = kTraceToConsole;
606*635a8641SAndroid Build Coastguard Worker       break;
607*635a8641SAndroid Build Coastguard Worker     default:
608*635a8641SAndroid Build Coastguard Worker       NOTREACHED();
609*635a8641SAndroid Build Coastguard Worker   }
610*635a8641SAndroid Build Coastguard Worker   if (enable_systrace_)
611*635a8641SAndroid Build Coastguard Worker     ret = ret + "," + kEnableSystrace;
612*635a8641SAndroid Build Coastguard Worker   if (enable_argument_filter_)
613*635a8641SAndroid Build Coastguard Worker     ret = ret + "," + kEnableArgumentFilter;
614*635a8641SAndroid Build Coastguard Worker   return ret;
615*635a8641SAndroid Build Coastguard Worker }
616*635a8641SAndroid Build Coastguard Worker 
617*635a8641SAndroid Build Coastguard Worker }  // namespace trace_event
618*635a8641SAndroid Build Coastguard Worker }  // namespace base
619