• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/scoped_add_feature_flags.h"
6 
7 #include <string_view>
8 
9 #include "base/base_switches.h"
10 #include "base/command_line.h"
11 #include "base/containers/contains.h"
12 #include "base/strings/strcat.h"
13 #include "base/strings/string_util.h"
14 
15 namespace base {
16 
ScopedAddFeatureFlags(CommandLine * command_line)17 ScopedAddFeatureFlags::ScopedAddFeatureFlags(CommandLine* command_line)
18     : command_line_(command_line) {
19   std::string enabled_features =
20       command_line->GetSwitchValueASCII(switches::kEnableFeatures);
21   std::string disabled_features =
22       command_line->GetSwitchValueASCII(switches::kDisableFeatures);
23   for (std::string_view feature :
24        FeatureList::SplitFeatureListString(enabled_features)) {
25     enabled_features_.emplace_back(feature);
26   }
27   for (std::string_view feature :
28        FeatureList::SplitFeatureListString(disabled_features)) {
29     disabled_features_.emplace_back(feature);
30   }
31 }
32 
~ScopedAddFeatureFlags()33 ScopedAddFeatureFlags::~ScopedAddFeatureFlags() {
34   command_line_->RemoveSwitch(switches::kEnableFeatures);
35   command_line_->AppendSwitchASCII(switches::kEnableFeatures,
36                                    JoinString(enabled_features_, ","));
37   command_line_->RemoveSwitch(switches::kDisableFeatures);
38   command_line_->AppendSwitchASCII(switches::kDisableFeatures,
39                                    JoinString(disabled_features_, ","));
40 }
41 
EnableIfNotSet(const Feature & feature)42 void ScopedAddFeatureFlags::EnableIfNotSet(const Feature& feature) {
43   AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/true);
44 }
45 
EnableIfNotSetWithParameter(const Feature & feature,std::string_view name,std::string_view value)46 void ScopedAddFeatureFlags::EnableIfNotSetWithParameter(
47     const Feature& feature,
48     std::string_view name,
49     std::string_view value) {
50   std::string suffix = StrCat({":", name, "/", value});
51   AddFeatureIfNotSet(feature, suffix, true /* enable */);
52 }
53 
DisableIfNotSet(const Feature & feature)54 void ScopedAddFeatureFlags::DisableIfNotSet(const Feature& feature) {
55   AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/false);
56 }
57 
IsEnabled(const Feature & feature)58 bool ScopedAddFeatureFlags::IsEnabled(const Feature& feature) {
59   return IsEnabledWithParameter(feature, /*parameter_name=*/"",
60                                 /*parameter_value=*/"");
61 }
62 
IsEnabledWithParameter(const Feature & feature,std::string_view parameter_name,std::string_view parameter_value)63 bool ScopedAddFeatureFlags::IsEnabledWithParameter(
64     const Feature& feature,
65     std::string_view parameter_name,
66     std::string_view parameter_value) {
67   std::string feature_name = feature.name;
68   if (!parameter_name.empty()) {
69     StrAppend(&feature_name, {":", parameter_name, "/", parameter_value});
70   }
71   if (Contains(disabled_features_, feature_name))
72     return false;
73   if (Contains(enabled_features_, feature_name))
74     return true;
75   return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
76 }
77 
AddFeatureIfNotSet(const Feature & feature,std::string_view suffix,bool enable)78 void ScopedAddFeatureFlags::AddFeatureIfNotSet(const Feature& feature,
79                                                std::string_view suffix,
80                                                bool enable) {
81   std::string feature_name = StrCat({feature.name, suffix});
82   if (Contains(enabled_features_, feature_name) ||
83       Contains(disabled_features_, feature_name)) {
84     return;
85   }
86   if (enable) {
87     enabled_features_.emplace_back(feature_name);
88   } else {
89     disabled_features_.emplace_back(feature_name);
90   }
91 }
92 
93 }  // namespace base
94