• 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 "base/base_switches.h"
8 #include "base/command_line.h"
9 #include "base/containers/contains.h"
10 #include "base/strings/strcat.h"
11 #include "base/strings/string_util.h"
12 
13 namespace base {
14 
ScopedAddFeatureFlags(CommandLine * command_line)15 ScopedAddFeatureFlags::ScopedAddFeatureFlags(CommandLine* command_line)
16     : command_line_(command_line) {
17   std::string enabled_features =
18       command_line->GetSwitchValueASCII(switches::kEnableFeatures);
19   std::string disabled_features =
20       command_line->GetSwitchValueASCII(switches::kDisableFeatures);
21   for (const StringPiece& feature :
22        FeatureList::SplitFeatureListString(enabled_features)) {
23     enabled_features_.emplace_back(feature);
24   }
25   for (const StringPiece& feature :
26        FeatureList::SplitFeatureListString(disabled_features)) {
27     disabled_features_.emplace_back(feature);
28   }
29 }
30 
~ScopedAddFeatureFlags()31 ScopedAddFeatureFlags::~ScopedAddFeatureFlags() {
32   command_line_->RemoveSwitch(switches::kEnableFeatures);
33   command_line_->AppendSwitchASCII(switches::kEnableFeatures,
34                                    JoinString(enabled_features_, ","));
35   command_line_->RemoveSwitch(switches::kDisableFeatures);
36   command_line_->AppendSwitchASCII(switches::kDisableFeatures,
37                                    JoinString(disabled_features_, ","));
38 }
39 
EnableIfNotSet(const Feature & feature)40 void ScopedAddFeatureFlags::EnableIfNotSet(const Feature& feature) {
41   AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/true);
42 }
43 
EnableIfNotSetWithParameter(const Feature & feature,StringPiece name,StringPiece value)44 void ScopedAddFeatureFlags::EnableIfNotSetWithParameter(const Feature& feature,
45                                                         StringPiece name,
46                                                         StringPiece value) {
47   std::string suffix = StrCat({":", name, "/", value});
48   AddFeatureIfNotSet(feature, suffix, true /* enable */);
49 }
50 
DisableIfNotSet(const Feature & feature)51 void ScopedAddFeatureFlags::DisableIfNotSet(const Feature& feature) {
52   AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/false);
53 }
54 
IsEnabled(const Feature & feature)55 bool ScopedAddFeatureFlags::IsEnabled(const Feature& feature) {
56   return IsEnabledWithParameter(feature, /*parameter_name=*/"",
57                                 /*parameter_value=*/"");
58 }
59 
IsEnabledWithParameter(const Feature & feature,StringPiece parameter_name,StringPiece parameter_value)60 bool ScopedAddFeatureFlags::IsEnabledWithParameter(
61     const Feature& feature,
62     StringPiece parameter_name,
63     StringPiece parameter_value) {
64   std::string feature_name = feature.name;
65   if (!parameter_name.empty()) {
66     StrAppend(&feature_name, {":", parameter_name, "/", parameter_value});
67   }
68   if (Contains(disabled_features_, feature_name))
69     return false;
70   if (Contains(enabled_features_, feature_name))
71     return true;
72   return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
73 }
74 
AddFeatureIfNotSet(const Feature & feature,StringPiece suffix,bool enable)75 void ScopedAddFeatureFlags::AddFeatureIfNotSet(const Feature& feature,
76                                                StringPiece suffix,
77                                                bool enable) {
78   std::string feature_name = StrCat({feature.name, suffix});
79   if (Contains(enabled_features_, feature_name) ||
80       Contains(disabled_features_, feature_name)) {
81     return;
82   }
83   if (enable) {
84     enabled_features_.emplace_back(feature_name);
85   } else {
86     disabled_features_.emplace_back(feature_name);
87   }
88 }
89 
90 }  // namespace base
91