OLD | NEW |
---|---|
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/trace_event/trace_config.h" | 5 #include "base/trace_event/trace_config.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 | 46 |
47 // String parameters that is used to parse memory dump config in trace config | 47 // String parameters that is used to parse memory dump config in trace config |
48 // string. | 48 // string. |
49 const char kMemoryDumpConfigParam[] = "memory_dump_config"; | 49 const char kMemoryDumpConfigParam[] = "memory_dump_config"; |
50 const char kTriggersParam[] = "triggers"; | 50 const char kTriggersParam[] = "triggers"; |
51 const char kPeriodicIntervalParam[] = "periodic_interval_ms"; | 51 const char kPeriodicIntervalParam[] = "periodic_interval_ms"; |
52 const char kModeParam[] = "mode"; | 52 const char kModeParam[] = "mode"; |
53 const char kHeapProfilerOptions[] = "heap_profiler_options"; | 53 const char kHeapProfilerOptions[] = "heap_profiler_options"; |
54 const char kBreakdownThresholdBytes[] = "breakdown_threshold_bytes"; | 54 const char kBreakdownThresholdBytes[] = "breakdown_threshold_bytes"; |
55 | 55 |
56 // String parameters used to parse category event filters. | |
57 const char kEventFiltersParam[] = "event_filters"; | |
58 const char kFilterPredicateParam[] = "filter_predicate"; | |
59 const char kFilterArgsParam[] = "filter_args"; | |
60 | |
56 // Default configuration of memory dumps. | 61 // Default configuration of memory dumps. |
57 const TraceConfig::MemoryDumpConfig::Trigger kDefaultHeavyMemoryDumpTrigger = { | 62 const TraceConfig::MemoryDumpConfig::Trigger kDefaultHeavyMemoryDumpTrigger = { |
58 2000, // periodic_interval_ms | 63 2000, // periodic_interval_ms |
59 MemoryDumpLevelOfDetail::DETAILED}; | 64 MemoryDumpLevelOfDetail::DETAILED}; |
60 const TraceConfig::MemoryDumpConfig::Trigger kDefaultLightMemoryDumpTrigger = { | 65 const TraceConfig::MemoryDumpConfig::Trigger kDefaultLightMemoryDumpTrigger = { |
61 250, // periodic_interval_ms | 66 250, // periodic_interval_ms |
62 MemoryDumpLevelOfDetail::LIGHT}; | 67 MemoryDumpLevelOfDetail::LIGHT}; |
63 | 68 |
64 class ConvertableTraceConfigToTraceFormat | 69 class ConvertableTraceConfigToTraceFormat |
65 : public base::trace_event::ConvertableToTraceFormat { | 70 : public base::trace_event::ConvertableToTraceFormat { |
66 public: | 71 public: |
67 explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config) | 72 explicit ConvertableTraceConfigToTraceFormat(const TraceConfig& trace_config) |
68 : trace_config_(trace_config) {} | 73 : trace_config_(trace_config) {} |
74 | |
69 ~ConvertableTraceConfigToTraceFormat() override {} | 75 ~ConvertableTraceConfigToTraceFormat() override {} |
76 | |
70 void AppendAsTraceFormat(std::string* out) const override { | 77 void AppendAsTraceFormat(std::string* out) const override { |
71 out->append(trace_config_.ToString()); | 78 out->append(trace_config_.ToString()); |
72 } | 79 } |
73 | 80 |
74 private: | 81 private: |
75 const TraceConfig trace_config_; | 82 const TraceConfig trace_config_; |
76 }; | 83 }; |
77 | 84 |
78 } // namespace | 85 } // namespace |
79 | 86 |
(...skipping 10 matching lines...) Expand all Loading... | |
90 TraceConfig::MemoryDumpConfig::MemoryDumpConfig( | 97 TraceConfig::MemoryDumpConfig::MemoryDumpConfig( |
91 const MemoryDumpConfig& other) = default; | 98 const MemoryDumpConfig& other) = default; |
92 | 99 |
93 TraceConfig::MemoryDumpConfig::~MemoryDumpConfig() {}; | 100 TraceConfig::MemoryDumpConfig::~MemoryDumpConfig() {}; |
94 | 101 |
95 void TraceConfig::MemoryDumpConfig::Clear() { | 102 void TraceConfig::MemoryDumpConfig::Clear() { |
96 triggers.clear(); | 103 triggers.clear(); |
97 heap_profiler_options.Clear(); | 104 heap_profiler_options.Clear(); |
98 } | 105 } |
99 | 106 |
107 TraceConfig::EventFilterConfig::EventFilterConfig( | |
108 const std::string& predicate_name) | |
109 : predicate_name_(predicate_name) {} | |
110 TraceConfig::EventFilterConfig::~EventFilterConfig() {} | |
111 | |
112 TraceConfig::EventFilterConfig::EventFilterConfig(const EventFilterConfig& tc) | |
113 : predicate_name_(tc.predicate_name_), | |
114 included_categories_(tc.included_categories_), | |
115 excluded_categories_(tc.excluded_categories_) { | |
116 if (tc.args_) | |
117 args_ = tc.args_->CreateDeepCopy(); | |
Primiano Tucci (use gerrit)
2016/05/27 17:47:06
I wonder, can you just say *this = tc here and reu
oystein (OOO til 10th of July)
2016/08/01 13:39:48
Done.
| |
118 } | |
119 | |
120 TraceConfig::EventFilterConfig& TraceConfig::EventFilterConfig::operator=( | |
121 const TraceConfig::EventFilterConfig& rhs) { | |
122 if (this == &rhs) | |
123 return *this; | |
124 | |
125 predicate_name_ = rhs.predicate_name_; | |
126 included_categories_ = rhs.included_categories_; | |
127 excluded_categories_ = rhs.excluded_categories_; | |
128 if (rhs.args_) | |
129 args_ = rhs.args_->CreateDeepCopy(); | |
130 | |
131 return *this; | |
132 } | |
133 | |
134 void TraceConfig::EventFilterConfig::AddIncludedCategory( | |
135 const std::string& category) { | |
136 included_categories_.push_back(category); | |
137 } | |
138 | |
139 void TraceConfig::EventFilterConfig::AddExcludedCategory( | |
140 const std::string& category) { | |
141 excluded_categories_.push_back(category); | |
142 } | |
143 | |
144 void TraceConfig::EventFilterConfig::SetArgs( | |
145 std::unique_ptr<base::DictionaryValue> args) { | |
146 args_ = std::move(args); | |
147 } | |
148 | |
149 bool TraceConfig::EventFilterConfig::IsCategoryGroupEnabled( | |
150 const char* category_group_name) const { | |
151 CStringTokenizer category_group_tokens( | |
152 category_group_name, category_group_name + strlen(category_group_name), | |
153 ","); | |
154 while (category_group_tokens.GetNext()) { | |
155 std::string category_group_token = category_group_tokens.token(); | |
156 | |
157 for (const auto& excluded_category : excluded_categories_) { | |
158 if (base::MatchPattern(category_group_token.c_str(), | |
Primiano Tucci (use gerrit)
2016/05/27 17:47:06
nit: i think you dont' need c_str as StringPiece h
oystein (OOO til 10th of July)
2016/08/01 13:39:48
Done.
| |
159 excluded_category.c_str())) { | |
160 return false; | |
161 } | |
162 } | |
163 | |
164 for (const auto& included_category : included_categories_) { | |
165 if (base::MatchPattern(category_group_token.c_str(), | |
166 included_category.c_str())) { | |
167 return true; | |
168 } | |
169 } | |
170 } | |
171 | |
172 return false; | |
173 } | |
174 | |
100 TraceConfig::TraceConfig() { | 175 TraceConfig::TraceConfig() { |
101 InitializeDefault(); | 176 InitializeDefault(); |
102 } | 177 } |
103 | 178 |
104 TraceConfig::TraceConfig(const std::string& category_filter_string, | 179 TraceConfig::TraceConfig(const std::string& category_filter_string, |
105 const std::string& trace_options_string) { | 180 const std::string& trace_options_string) { |
106 InitializeFromStrings(category_filter_string, trace_options_string); | 181 InitializeFromStrings(category_filter_string, trace_options_string); |
107 } | 182 } |
108 | 183 |
109 TraceConfig::TraceConfig(const std::string& category_filter_string, | 184 TraceConfig::TraceConfig(const std::string& category_filter_string, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 | 216 |
142 TraceConfig::TraceConfig(const TraceConfig& tc) | 217 TraceConfig::TraceConfig(const TraceConfig& tc) |
143 : record_mode_(tc.record_mode_), | 218 : record_mode_(tc.record_mode_), |
144 enable_sampling_(tc.enable_sampling_), | 219 enable_sampling_(tc.enable_sampling_), |
145 enable_systrace_(tc.enable_systrace_), | 220 enable_systrace_(tc.enable_systrace_), |
146 enable_argument_filter_(tc.enable_argument_filter_), | 221 enable_argument_filter_(tc.enable_argument_filter_), |
147 memory_dump_config_(tc.memory_dump_config_), | 222 memory_dump_config_(tc.memory_dump_config_), |
148 included_categories_(tc.included_categories_), | 223 included_categories_(tc.included_categories_), |
149 disabled_categories_(tc.disabled_categories_), | 224 disabled_categories_(tc.disabled_categories_), |
150 excluded_categories_(tc.excluded_categories_), | 225 excluded_categories_(tc.excluded_categories_), |
151 synthetic_delays_(tc.synthetic_delays_) {} | 226 synthetic_delays_(tc.synthetic_delays_), |
227 event_filters_(tc.event_filters_) {} | |
152 | 228 |
153 TraceConfig::~TraceConfig() { | 229 TraceConfig::~TraceConfig() { |
154 } | 230 } |
155 | 231 |
156 TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) { | 232 TraceConfig& TraceConfig::operator=(const TraceConfig& rhs) { |
157 if (this == &rhs) | 233 if (this == &rhs) |
158 return *this; | 234 return *this; |
159 | 235 |
160 record_mode_ = rhs.record_mode_; | 236 record_mode_ = rhs.record_mode_; |
161 enable_sampling_ = rhs.enable_sampling_; | 237 enable_sampling_ = rhs.enable_sampling_; |
162 enable_systrace_ = rhs.enable_systrace_; | 238 enable_systrace_ = rhs.enable_systrace_; |
163 enable_argument_filter_ = rhs.enable_argument_filter_; | 239 enable_argument_filter_ = rhs.enable_argument_filter_; |
164 memory_dump_config_ = rhs.memory_dump_config_; | 240 memory_dump_config_ = rhs.memory_dump_config_; |
165 included_categories_ = rhs.included_categories_; | 241 included_categories_ = rhs.included_categories_; |
166 disabled_categories_ = rhs.disabled_categories_; | 242 disabled_categories_ = rhs.disabled_categories_; |
167 excluded_categories_ = rhs.excluded_categories_; | 243 excluded_categories_ = rhs.excluded_categories_; |
168 synthetic_delays_ = rhs.synthetic_delays_; | 244 synthetic_delays_ = rhs.synthetic_delays_; |
245 event_filters_ = rhs.event_filters_; | |
169 return *this; | 246 return *this; |
170 } | 247 } |
171 | 248 |
172 const TraceConfig::StringList& TraceConfig::GetSyntheticDelayValues() const { | 249 const TraceConfig::StringList& TraceConfig::GetSyntheticDelayValues() const { |
173 return synthetic_delays_; | 250 return synthetic_delays_; |
174 } | 251 } |
175 | 252 |
176 std::string TraceConfig::ToString() const { | 253 std::string TraceConfig::ToString() const { |
177 base::DictionaryValue dict; | 254 base::DictionaryValue dict; |
178 ToDict(dict); | 255 ToDict(dict); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 void TraceConfig::Clear() { | 374 void TraceConfig::Clear() { |
298 record_mode_ = RECORD_UNTIL_FULL; | 375 record_mode_ = RECORD_UNTIL_FULL; |
299 enable_sampling_ = false; | 376 enable_sampling_ = false; |
300 enable_systrace_ = false; | 377 enable_systrace_ = false; |
301 enable_argument_filter_ = false; | 378 enable_argument_filter_ = false; |
302 included_categories_.clear(); | 379 included_categories_.clear(); |
303 disabled_categories_.clear(); | 380 disabled_categories_.clear(); |
304 excluded_categories_.clear(); | 381 excluded_categories_.clear(); |
305 synthetic_delays_.clear(); | 382 synthetic_delays_.clear(); |
306 memory_dump_config_.Clear(); | 383 memory_dump_config_.Clear(); |
384 event_filters_.clear(); | |
307 } | 385 } |
308 | 386 |
309 void TraceConfig::InitializeDefault() { | 387 void TraceConfig::InitializeDefault() { |
310 record_mode_ = RECORD_UNTIL_FULL; | 388 record_mode_ = RECORD_UNTIL_FULL; |
311 enable_sampling_ = false; | 389 enable_sampling_ = false; |
312 enable_systrace_ = false; | 390 enable_systrace_ = false; |
313 enable_argument_filter_ = false; | 391 enable_argument_filter_ = false; |
314 excluded_categories_.push_back("*Debug"); | 392 excluded_categories_.push_back("*Debug"); |
315 excluded_categories_.push_back("*Test"); | 393 excluded_categories_.push_back("*Test"); |
316 } | 394 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 | 436 |
359 if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) { | 437 if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) { |
360 // If dump triggers not set, the client is using the legacy with just | 438 // If dump triggers not set, the client is using the legacy with just |
361 // category enabled. So, use the default periodic dump config. | 439 // category enabled. So, use the default periodic dump config. |
362 const base::DictionaryValue* memory_dump_config = nullptr; | 440 const base::DictionaryValue* memory_dump_config = nullptr; |
363 if (dict.GetDictionary(kMemoryDumpConfigParam, &memory_dump_config)) | 441 if (dict.GetDictionary(kMemoryDumpConfigParam, &memory_dump_config)) |
364 SetMemoryDumpConfig(*memory_dump_config); | 442 SetMemoryDumpConfig(*memory_dump_config); |
365 else | 443 else |
366 SetDefaultMemoryDumpConfig(); | 444 SetDefaultMemoryDumpConfig(); |
367 } | 445 } |
446 | |
447 const base::ListValue* category_event_filters = nullptr; | |
448 if (dict.GetList(kEventFiltersParam, &category_event_filters)) | |
449 SetEventFilters(*category_event_filters); | |
368 } | 450 } |
369 | 451 |
370 void TraceConfig::InitializeFromConfigString(const std::string& config_string) { | 452 void TraceConfig::InitializeFromConfigString(const std::string& config_string) { |
371 std::unique_ptr<Value> value(JSONReader::Read(config_string)); | 453 std::unique_ptr<Value> value(JSONReader::Read(config_string)); |
372 if (!value) | 454 if (!value) |
373 return InitializeDefault(); | 455 return InitializeDefault(); |
374 | 456 |
375 const DictionaryValue* dict = nullptr; | 457 const DictionaryValue* dict = nullptr; |
376 bool is_dict = value->GetAsDictionary(&dict); | 458 bool is_dict = value->GetAsDictionary(&dict); |
377 | 459 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 } | 636 } |
555 } | 637 } |
556 } | 638 } |
557 | 639 |
558 void TraceConfig::SetDefaultMemoryDumpConfig() { | 640 void TraceConfig::SetDefaultMemoryDumpConfig() { |
559 memory_dump_config_.Clear(); | 641 memory_dump_config_.Clear(); |
560 memory_dump_config_.triggers.push_back(kDefaultHeavyMemoryDumpTrigger); | 642 memory_dump_config_.triggers.push_back(kDefaultHeavyMemoryDumpTrigger); |
561 memory_dump_config_.triggers.push_back(kDefaultLightMemoryDumpTrigger); | 643 memory_dump_config_.triggers.push_back(kDefaultLightMemoryDumpTrigger); |
562 } | 644 } |
563 | 645 |
646 void TraceConfig::SetEventFilters( | |
647 const base::ListValue& category_event_filters) { | |
648 event_filters_.clear(); | |
649 | |
650 for (size_t i = 0; i < category_event_filters.GetSize(); ++i) { | |
651 const base::DictionaryValue* event_filter = nullptr; | |
652 if (!category_event_filters.GetDictionary(i, &event_filter)) | |
653 continue; | |
654 | |
655 std::string predicate_name; | |
656 if (!event_filter->GetString(kFilterPredicateParam, &predicate_name)) { | |
657 LOG(ERROR) << "Invalid predicate name in category event filter."; | |
Primiano Tucci (use gerrit)
2016/05/27 17:47:06
I might be wrong but I seem to remember that LOG (
oystein (OOO til 10th of July)
2016/08/01 13:39:48
Done.
| |
658 continue; | |
659 } | |
660 | |
661 EventFilterConfig new_config(predicate_name); | |
662 const base::ListValue* included_list = nullptr; | |
663 if (!event_filter->GetList(kIncludedCategoriesParam, &included_list)) { | |
664 LOG(ERROR) << "Missing included_categories in category event filter."; | |
665 continue; | |
666 } | |
667 | |
668 for (size_t i = 0; i < included_list->GetSize(); ++i) { | |
Primiano Tucci (use gerrit)
2016/05/27 17:47:06
note you use i outside and inside the scope. I tho
oystein (OOO til 10th of July)
2016/08/01 13:39:48
Done.
| |
669 std::string category; | |
670 if (included_list->GetString(i, &category)) | |
671 new_config.AddIncludedCategory(category); | |
672 } | |
673 | |
674 const base::ListValue* excluded_list = nullptr; | |
675 if (event_filter->GetList(kExcludedCategoriesParam, &excluded_list)) { | |
676 for (size_t i = 0; i < excluded_list->GetSize(); ++i) { | |
677 std::string category; | |
678 if (excluded_list->GetString(i, &category)) | |
679 new_config.AddExcludedCategory(category); | |
680 } | |
681 } | |
682 | |
683 const base::DictionaryValue* args_dict = nullptr; | |
684 if (event_filter->GetDictionary(kFilterArgsParam, &args_dict)) | |
685 new_config.SetArgs(args_dict->CreateDeepCopy()); | |
686 | |
687 event_filters_.push_back(new_config); | |
688 } | |
689 } | |
690 | |
564 void TraceConfig::ToDict(base::DictionaryValue& dict) const { | 691 void TraceConfig::ToDict(base::DictionaryValue& dict) const { |
565 switch (record_mode_) { | 692 switch (record_mode_) { |
566 case RECORD_UNTIL_FULL: | 693 case RECORD_UNTIL_FULL: |
567 dict.SetString(kRecordModeParam, kRecordUntilFull); | 694 dict.SetString(kRecordModeParam, kRecordUntilFull); |
568 break; | 695 break; |
569 case RECORD_CONTINUOUSLY: | 696 case RECORD_CONTINUOUSLY: |
570 dict.SetString(kRecordModeParam, kRecordContinuously); | 697 dict.SetString(kRecordModeParam, kRecordContinuously); |
571 break; | 698 break; |
572 case RECORD_AS_MUCH_AS_POSSIBLE: | 699 case RECORD_AS_MUCH_AS_POSSIBLE: |
573 dict.SetString(kRecordModeParam, kRecordAsMuchAsPossible); | 700 dict.SetString(kRecordModeParam, kRecordAsMuchAsPossible); |
(...skipping 21 matching lines...) Expand all Loading... | |
595 dict.SetBoolean(kEnableArgumentFilterParam, false); | 722 dict.SetBoolean(kEnableArgumentFilterParam, false); |
596 | 723 |
597 StringList categories(included_categories_); | 724 StringList categories(included_categories_); |
598 categories.insert(categories.end(), | 725 categories.insert(categories.end(), |
599 disabled_categories_.begin(), | 726 disabled_categories_.begin(), |
600 disabled_categories_.end()); | 727 disabled_categories_.end()); |
601 AddCategoryToDict(dict, kIncludedCategoriesParam, categories); | 728 AddCategoryToDict(dict, kIncludedCategoriesParam, categories); |
602 AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_); | 729 AddCategoryToDict(dict, kExcludedCategoriesParam, excluded_categories_); |
603 AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_); | 730 AddCategoryToDict(dict, kSyntheticDelaysParam, synthetic_delays_); |
604 | 731 |
732 if (!event_filters_.empty()) { | |
733 std::unique_ptr<base::ListValue> filter_list(new base::ListValue()); | |
734 for (const EventFilterConfig& filter : event_filters_) { | |
735 std::unique_ptr<base::DictionaryValue> filter_dict( | |
736 new base::DictionaryValue()); | |
737 filter_dict->SetString(kFilterPredicateParam, filter.predicate_name()); | |
738 | |
739 std::unique_ptr<base::ListValue> included_categories_list( | |
740 new base::ListValue()); | |
741 for (const std::string& included_category : filter.included_categories()) | |
742 included_categories_list->AppendString(included_category); | |
743 | |
744 filter_dict->Set(kIncludedCategoriesParam, | |
745 std::move(included_categories_list)); | |
746 | |
747 if (!filter.excluded_categories().empty()) { | |
748 std::unique_ptr<base::ListValue> excluded_categories_list( | |
749 new base::ListValue()); | |
750 for (const std::string& excluded_category : | |
751 filter.excluded_categories()) | |
752 excluded_categories_list->AppendString(excluded_category); | |
753 | |
754 filter_dict->Set(kExcludedCategoriesParam, | |
755 std::move(excluded_categories_list)); | |
756 } | |
757 | |
758 if (filter.filter_args()) | |
759 filter_dict->Set(kFilterArgsParam, | |
760 filter.filter_args()->CreateDeepCopy()); | |
761 | |
762 filter_list->Append(std::move(filter_dict)); | |
763 } | |
764 dict.Set(kEventFiltersParam, std::move(filter_list)); | |
765 } | |
766 | |
605 if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) { | 767 if (IsCategoryEnabled(MemoryDumpManager::kTraceCategory)) { |
606 std::unique_ptr<base::DictionaryValue> memory_dump_config( | 768 std::unique_ptr<base::DictionaryValue> memory_dump_config( |
607 new base::DictionaryValue()); | 769 new base::DictionaryValue()); |
608 std::unique_ptr<base::ListValue> triggers_list(new base::ListValue()); | 770 std::unique_ptr<base::ListValue> triggers_list(new base::ListValue()); |
609 for (const MemoryDumpConfig::Trigger& config | 771 for (const MemoryDumpConfig::Trigger& config |
610 : memory_dump_config_.triggers) { | 772 : memory_dump_config_.triggers) { |
611 std::unique_ptr<base::DictionaryValue> trigger_dict( | 773 std::unique_ptr<base::DictionaryValue> trigger_dict( |
612 new base::DictionaryValue()); | 774 new base::DictionaryValue()); |
613 trigger_dict->SetInteger(kPeriodicIntervalParam, | 775 trigger_dict->SetInteger(kPeriodicIntervalParam, |
614 static_cast<int>(config.periodic_interval_ms)); | 776 static_cast<int>(config.periodic_interval_ms)); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 str.at(0) == ' ' || | 883 str.at(0) == ' ' || |
722 str.at(str.length() - 1) == ' '; | 884 str.at(str.length() - 1) == ' '; |
723 } | 885 } |
724 | 886 |
725 bool TraceConfig::HasIncludedPatterns() const { | 887 bool TraceConfig::HasIncludedPatterns() const { |
726 return !included_categories_.empty(); | 888 return !included_categories_.empty(); |
727 } | 889 } |
728 | 890 |
729 } // namespace trace_event | 891 } // namespace trace_event |
730 } // namespace base | 892 } // namespace base |
OLD | NEW |