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