123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/trace_event/trace_config_category_filter.h"
- #include "base/memory/ptr_util.h"
- #include "base/strings/pattern.h"
- #include "base/strings/string_piece.h"
- #include "base/strings/string_split.h"
- #include "base/strings/string_tokenizer.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/trace_event/trace_event.h"
- namespace base {
- namespace trace_event {
- namespace {
- const char kIncludedCategoriesParam[] = "included_categories";
- const char kExcludedCategoriesParam[] = "excluded_categories";
- }
- TraceConfigCategoryFilter::TraceConfigCategoryFilter() = default;
- TraceConfigCategoryFilter::TraceConfigCategoryFilter(
- const TraceConfigCategoryFilter& other) = default;
- TraceConfigCategoryFilter::~TraceConfigCategoryFilter() = default;
- TraceConfigCategoryFilter& TraceConfigCategoryFilter::operator=(
- const TraceConfigCategoryFilter& rhs) = default;
- void TraceConfigCategoryFilter::InitializeFromString(
- const StringPiece& category_filter_string) {
- std::vector<StringPiece> split = SplitStringPiece(
- category_filter_string, ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
- for (const StringPiece& category : split) {
- // Ignore empty categories.
- if (category.empty())
- continue;
- if (category.front() == '-') {
- // Excluded categories start with '-'.
- // Remove '-' from category string.
- excluded_categories_.emplace_back(category.substr(1));
- } else if (StartsWith(category, TRACE_DISABLED_BY_DEFAULT(""))) {
- disabled_categories_.emplace_back(category);
- } else {
- included_categories_.emplace_back(category);
- }
- }
- }
- void TraceConfigCategoryFilter::InitializeFromConfigDict(const Value& dict) {
- const Value* included_category_list =
- dict.FindListKey(kIncludedCategoriesParam);
- if (included_category_list)
- SetCategoriesFromIncludedList(*included_category_list);
- const Value* excluded_category_list =
- dict.FindListKey(kExcludedCategoriesParam);
- if (excluded_category_list)
- SetCategoriesFromExcludedList(*excluded_category_list);
- }
- bool TraceConfigCategoryFilter::IsCategoryGroupEnabled(
- const StringPiece& category_group_name) const {
- bool had_enabled_by_default = false;
- DCHECK(!category_group_name.empty());
- CStringTokenizer category_group_tokens(category_group_name.begin(),
- category_group_name.end(), ",");
- while (category_group_tokens.GetNext()) {
- StringPiece category_group_token = category_group_tokens.token_piece();
- // Don't allow empty tokens, nor tokens with leading or trailing space.
- DCHECK(IsCategoryNameAllowed(category_group_token))
- << "Disallowed category string";
- if (IsCategoryEnabled(category_group_token))
- return true;
- if (!MatchPattern(category_group_token, TRACE_DISABLED_BY_DEFAULT("*")))
- had_enabled_by_default = true;
- }
- // Do a second pass to check for explicitly disabled categories
- // (those explicitly enabled have priority due to first pass).
- category_group_tokens.Reset();
- bool category_group_disabled = false;
- while (category_group_tokens.GetNext()) {
- StringPiece category_group_token = category_group_tokens.token_piece();
- for (const std::string& category : excluded_categories_) {
- if (MatchPattern(category_group_token, category)) {
- // Current token of category_group_name is present in excluded_list.
- // Flag the exclusion and proceed further to check if any of the
- // remaining categories of category_group_name is not present in the
- // excluded_ list.
- category_group_disabled = true;
- break;
- }
- // One of the category of category_group_name is not present in
- // excluded_ list. So, if it's not a disabled-by-default category,
- // it has to be included_ list. Enable the category_group_name
- // for recording.
- if (!MatchPattern(category_group_token, TRACE_DISABLED_BY_DEFAULT("*")))
- category_group_disabled = false;
- }
- // One of the categories present in category_group_name is not present in
- // excluded_ list. Implies this category_group_name group can be enabled
- // for recording, since one of its groups is enabled for recording.
- if (!category_group_disabled)
- break;
- }
- // If the category group is not excluded, and there are no included patterns
- // we consider this category group enabled, as long as it had categories
- // other than disabled-by-default.
- return !category_group_disabled && had_enabled_by_default &&
- included_categories_.empty();
- }
- bool TraceConfigCategoryFilter::IsCategoryEnabled(
- const StringPiece& category_name) const {
- // Check the disabled- filters and the disabled-* wildcard first so that a
- // "*" filter does not include the disabled.
- for (const std::string& category : disabled_categories_) {
- if (MatchPattern(category_name, category))
- return true;
- }
- if (MatchPattern(category_name, TRACE_DISABLED_BY_DEFAULT("*")))
- return false;
- for (const std::string& category : included_categories_) {
- if (MatchPattern(category_name, category))
- return true;
- }
- return false;
- }
- void TraceConfigCategoryFilter::Merge(const TraceConfigCategoryFilter& config) {
- // Keep included patterns only if both filters have an included entry.
- // Otherwise, one of the filter was specifying "*" and we want to honor the
- // broadest filter.
- if (!included_categories_.empty() && !config.included_categories_.empty()) {
- included_categories_.insert(included_categories_.end(),
- config.included_categories_.begin(),
- config.included_categories_.end());
- } else {
- included_categories_.clear();
- }
- disabled_categories_.insert(disabled_categories_.end(),
- config.disabled_categories_.begin(),
- config.disabled_categories_.end());
- excluded_categories_.insert(excluded_categories_.end(),
- config.excluded_categories_.begin(),
- config.excluded_categories_.end());
- }
- void TraceConfigCategoryFilter::Clear() {
- included_categories_.clear();
- disabled_categories_.clear();
- excluded_categories_.clear();
- }
- void TraceConfigCategoryFilter::ToDict(Value::Dict& dict) const {
- StringList categories(included_categories_);
- categories.insert(categories.end(), disabled_categories_.begin(),
- disabled_categories_.end());
- AddCategoriesToDict(categories, kIncludedCategoriesParam, dict);
- AddCategoriesToDict(excluded_categories_, kExcludedCategoriesParam, dict);
- }
- std::string TraceConfigCategoryFilter::ToFilterString() const {
- std::string filter_string;
- WriteCategoryFilterString(included_categories_, &filter_string, true);
- WriteCategoryFilterString(disabled_categories_, &filter_string, true);
- WriteCategoryFilterString(excluded_categories_, &filter_string, false);
- return filter_string;
- }
- void TraceConfigCategoryFilter::SetCategoriesFromIncludedList(
- const Value& included_list) {
- included_categories_.clear();
- for (const Value& item : included_list.GetListDeprecated()) {
- if (!item.is_string())
- continue;
- const std::string& category = item.GetString();
- if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")),
- TRACE_DISABLED_BY_DEFAULT("")) == 0) {
- disabled_categories_.push_back(category);
- } else {
- included_categories_.push_back(category);
- }
- }
- }
- void TraceConfigCategoryFilter::SetCategoriesFromExcludedList(
- const Value& excluded_list) {
- excluded_categories_.clear();
- for (const Value& item : excluded_list.GetListDeprecated()) {
- if (item.is_string())
- excluded_categories_.push_back(item.GetString());
- }
- }
- void TraceConfigCategoryFilter::AddCategoriesToDict(
- const StringList& categories,
- const char* param,
- Value::Dict& dict) const {
- if (categories.empty())
- return;
- Value::List list;
- for (const std::string& category : categories)
- list.Append(category);
- dict.Set(param, std::move(list));
- }
- void TraceConfigCategoryFilter::WriteCategoryFilterString(
- const StringList& values,
- std::string* out,
- bool included) const {
- bool prepend_comma = !out->empty();
- int token_cnt = 0;
- for (const std::string& category : values) {
- if (token_cnt > 0 || prepend_comma)
- StringAppendF(out, ",");
- StringAppendF(out, "%s%s", (included ? "" : "-"), category.c_str());
- ++token_cnt;
- }
- }
- // static
- bool TraceConfigCategoryFilter::IsCategoryNameAllowed(StringPiece str) {
- return !str.empty() && str.front() != ' ' && str.back() != ' ';
- }
- } // namespace trace_event
- } // namespace base
|