OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "extensions/common/feature_switch.h" | 5 #include "extensions/common/feature_switch.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "extensions/common/switches.h" | 12 #include "extensions/common/switches.h" |
13 | 13 |
14 namespace extensions { | 14 namespace extensions { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 // The switch media-router is defined in chrome/common/chrome_switches.cc, but | |
19 // we can't depend on chrome here. | |
20 const char kMediaRouterFlag[] = "media-router"; | |
21 | |
18 const char kEnableMediaRouterExperiment[] = "EnableMediaRouter"; | 22 const char kEnableMediaRouterExperiment[] = "EnableMediaRouter"; |
19 const char kEnableMediaRouterWithCastExtensionExperiment[] = | 23 const char kEnableMediaRouterWithCastExtensionExperiment[] = |
20 "EnableMediaRouterWithCastExtension"; | 24 "EnableMediaRouterWithCastExtension"; |
21 const char kExtensionActionRedesignExperiment[] = "ExtensionActionRedesign"; | 25 const char kExtensionActionRedesignExperiment[] = "ExtensionActionRedesign"; |
22 | 26 |
27 const char* kMediaRouterRequiredExperiments[] = { | |
28 kEnableMediaRouterExperiment, kExtensionActionRedesignExperiment}; | |
29 const char* kMediaRouterWithCastExtensionRequiredExperiments[] = { | |
30 kEnableMediaRouterWithCastExtensionExperiment, | |
31 kExtensionActionRedesignExperiment}; | |
32 | |
23 class CommonSwitches { | 33 class CommonSwitches { |
24 public: | 34 public: |
25 CommonSwitches() | 35 CommonSwitches() |
26 : easy_off_store_install(nullptr, FeatureSwitch::DEFAULT_DISABLED), | 36 : easy_off_store_install(nullptr, FeatureSwitch::DEFAULT_DISABLED), |
27 force_dev_mode_highlighting(switches::kForceDevModeHighlighting, | 37 force_dev_mode_highlighting(switches::kForceDevModeHighlighting, |
28 FeatureSwitch::DEFAULT_DISABLED), | 38 FeatureSwitch::DEFAULT_DISABLED), |
29 prompt_for_external_extensions( | 39 prompt_for_external_extensions( |
30 #if defined(CHROMIUM_BUILD) | 40 #if defined(CHROMIUM_BUILD) |
31 switches::kPromptForExternalExtensions, | 41 switches::kPromptForExternalExtensions, |
32 #else | 42 #else |
(...skipping 11 matching lines...) Expand all Loading... | |
44 kExtensionActionRedesignExperiment, | 54 kExtensionActionRedesignExperiment, |
45 FeatureSwitch::DEFAULT_DISABLED), | 55 FeatureSwitch::DEFAULT_DISABLED), |
46 extension_action_redesign_override(switches::kExtensionActionRedesign, | 56 extension_action_redesign_override(switches::kExtensionActionRedesign, |
47 FeatureSwitch::DEFAULT_ENABLED), | 57 FeatureSwitch::DEFAULT_ENABLED), |
48 scripts_require_action(switches::kScriptsRequireAction, | 58 scripts_require_action(switches::kScriptsRequireAction, |
49 FeatureSwitch::DEFAULT_DISABLED), | 59 FeatureSwitch::DEFAULT_DISABLED), |
50 embedded_extension_options(switches::kEmbeddedExtensionOptions, | 60 embedded_extension_options(switches::kEmbeddedExtensionOptions, |
51 FeatureSwitch::DEFAULT_DISABLED), | 61 FeatureSwitch::DEFAULT_DISABLED), |
52 trace_app_source(switches::kTraceAppSource, | 62 trace_app_source(switches::kTraceAppSource, |
53 FeatureSwitch::DEFAULT_ENABLED), | 63 FeatureSwitch::DEFAULT_ENABLED), |
54 // The switch media-router is defined in | 64 media_router(kMediaRouterFlag, |
55 // chrome/common/chrome_switches.cc, but we can't depend on chrome here. | 65 std::vector<std::string>( |
56 media_router("media-router", | 66 kMediaRouterRequiredExperiments, |
57 kEnableMediaRouterExperiment, | 67 kMediaRouterRequiredExperiments + |
68 arraysize(kMediaRouterRequiredExperiments)), | |
58 FeatureSwitch::DEFAULT_DISABLED), | 69 FeatureSwitch::DEFAULT_DISABLED), |
59 media_router_with_cast_extension( | 70 media_router_with_cast_extension( |
60 "media-router", | 71 kMediaRouterFlag, |
61 kEnableMediaRouterWithCastExtensionExperiment, | 72 std::vector<std::string>( |
73 kMediaRouterWithCastExtensionRequiredExperiments, | |
74 kMediaRouterWithCastExtensionRequiredExperiments + | |
75 arraysize( | |
76 kMediaRouterWithCastExtensionRequiredExperiments)), | |
62 FeatureSwitch::DEFAULT_DISABLED) { | 77 FeatureSwitch::DEFAULT_DISABLED) { |
63 } | 78 } |
64 | 79 |
65 // Enables extensions to be easily installed from sites other than the web | 80 // Enables extensions to be easily installed from sites other than the web |
66 // store. | 81 // store. |
67 FeatureSwitch easy_off_store_install; | 82 FeatureSwitch easy_off_store_install; |
68 | 83 |
69 FeatureSwitch force_dev_mode_highlighting; | 84 FeatureSwitch force_dev_mode_highlighting; |
70 | 85 |
71 // Should we prompt the user before allowing external extensions to install? | 86 // Should we prompt the user before allowing external extensions to install? |
(...skipping 28 matching lines...) Expand all Loading... | |
100 FeatureSwitch* FeatureSwitch::error_console() { | 115 FeatureSwitch* FeatureSwitch::error_console() { |
101 return &g_common_switches.Get().error_console; | 116 return &g_common_switches.Get().error_console; |
102 } | 117 } |
103 FeatureSwitch* FeatureSwitch::enable_override_bookmarks_ui() { | 118 FeatureSwitch* FeatureSwitch::enable_override_bookmarks_ui() { |
104 return &g_common_switches.Get().enable_override_bookmarks_ui; | 119 return &g_common_switches.Get().enable_override_bookmarks_ui; |
105 } | 120 } |
106 FeatureSwitch* FeatureSwitch::extension_action_redesign() { | 121 FeatureSwitch* FeatureSwitch::extension_action_redesign() { |
107 // Force-enable the redesigned extension action toolbar when the Media Router | 122 // Force-enable the redesigned extension action toolbar when the Media Router |
108 // is enabled. Should be removed when the toolbar redesign is used by default. | 123 // is enabled. Should be removed when the toolbar redesign is used by default. |
109 // See crbug.com/514694 | 124 // See crbug.com/514694 |
125 // Note that if Media Router is enabled by experiment, it implies that the | |
126 // extension action redesign is also enabled by experiment. Thus it is fine | |
127 // to return the override switch. | |
110 // TODO(kmarshall): Remove this override. | 128 // TODO(kmarshall): Remove this override. |
111 if (media_router()->IsEnabled()) | 129 if (media_router()->IsEnabled()) |
112 return &g_common_switches.Get().extension_action_redesign_override; | 130 return &g_common_switches.Get().extension_action_redesign_override; |
113 | 131 |
114 return &g_common_switches.Get().extension_action_redesign; | 132 return &g_common_switches.Get().extension_action_redesign; |
115 } | 133 } |
116 FeatureSwitch* FeatureSwitch::scripts_require_action() { | 134 FeatureSwitch* FeatureSwitch::scripts_require_action() { |
117 return &g_common_switches.Get().scripts_require_action; | 135 return &g_common_switches.Get().scripts_require_action; |
118 } | 136 } |
119 FeatureSwitch* FeatureSwitch::embedded_extension_options() { | 137 FeatureSwitch* FeatureSwitch::embedded_extension_options() { |
(...skipping 25 matching lines...) Expand all Loading... | |
145 DefaultValue default_value) | 163 DefaultValue default_value) |
146 : FeatureSwitch(base::CommandLine::ForCurrentProcess(), | 164 : FeatureSwitch(base::CommandLine::ForCurrentProcess(), |
147 switch_name, | 165 switch_name, |
148 default_value) {} | 166 default_value) {} |
149 | 167 |
150 FeatureSwitch::FeatureSwitch(const char* switch_name, | 168 FeatureSwitch::FeatureSwitch(const char* switch_name, |
151 const char* field_trial_name, | 169 const char* field_trial_name, |
152 DefaultValue default_value) | 170 DefaultValue default_value) |
153 : FeatureSwitch(base::CommandLine::ForCurrentProcess(), | 171 : FeatureSwitch(base::CommandLine::ForCurrentProcess(), |
154 switch_name, | 172 switch_name, |
155 field_trial_name, | 173 std::vector<std::string>(1, field_trial_name), |
174 default_value) {} | |
175 | |
176 FeatureSwitch::FeatureSwitch( | |
177 const char* switch_name, | |
178 const std::vector<std::string>& required_field_trials, | |
179 DefaultValue default_value) | |
180 : FeatureSwitch(base::CommandLine::ForCurrentProcess(), | |
181 switch_name, | |
182 required_field_trials, | |
156 default_value) {} | 183 default_value) {} |
157 | 184 |
158 FeatureSwitch::FeatureSwitch(const base::CommandLine* command_line, | 185 FeatureSwitch::FeatureSwitch(const base::CommandLine* command_line, |
159 const char* switch_name, | 186 const char* switch_name, |
160 DefaultValue default_value) | 187 DefaultValue default_value) |
161 : FeatureSwitch(command_line, switch_name, nullptr, default_value) {} | 188 : FeatureSwitch(command_line, |
189 switch_name, | |
190 std::vector<std::string>(), | |
191 default_value) {} | |
162 | 192 |
163 FeatureSwitch::FeatureSwitch(const base::CommandLine* command_line, | 193 FeatureSwitch::FeatureSwitch( |
164 const char* switch_name, | 194 const base::CommandLine* command_line, |
165 const char* field_trial_name, | 195 const char* switch_name, |
166 DefaultValue default_value) | 196 const std::vector<std::string>& required_field_trials, |
197 DefaultValue default_value) | |
167 : command_line_(command_line), | 198 : command_line_(command_line), |
168 switch_name_(switch_name), | 199 switch_name_(switch_name), |
169 field_trial_name_(field_trial_name), | 200 required_field_trials_(required_field_trials), |
170 default_value_(default_value == DEFAULT_ENABLED), | 201 default_value_(default_value == DEFAULT_ENABLED), |
171 override_value_(OVERRIDE_NONE) {} | 202 override_value_(OVERRIDE_NONE) {} |
172 | 203 |
204 FeatureSwitch::~FeatureSwitch(){}; | |
205 | |
173 bool FeatureSwitch::IsEnabled() const { | 206 bool FeatureSwitch::IsEnabled() const { |
174 if (override_value_ != OVERRIDE_NONE) | 207 if (override_value_ != OVERRIDE_NONE) |
175 return override_value_ == OVERRIDE_ENABLED; | 208 return override_value_ == OVERRIDE_ENABLED; |
176 | 209 |
177 if (!switch_name_) | 210 if (!switch_name_) |
178 return default_value_; | 211 return default_value_; |
179 | 212 |
180 std::string temp = command_line_->GetSwitchValueASCII(switch_name_); | 213 std::string temp = command_line->GetSwitchValueASCII(switch_name_); |
181 std::string switch_value; | 214 std::string switch_value; |
182 base::TrimWhitespaceASCII(temp, base::TRIM_ALL, &switch_value); | 215 base::TrimWhitespaceASCII(temp, base::TRIM_ALL, &switch_value); |
183 | 216 |
184 if (switch_value == "1") | 217 if (switch_value == "1") |
185 return true; | 218 return true; |
186 | 219 |
187 if (switch_value == "0") | 220 if (switch_value == "0") |
188 return false; | 221 return false; |
189 | 222 |
223 // TODO(imcheng): Don't check |default_value_|. Otherwise, we could improperly | |
224 // ignore an enable/disable switch if there is a field trial active. | |
225 // crbug.com/585569 | |
190 if (!default_value_ && command_line_->HasSwitch(GetLegacyEnableFlag())) | 226 if (!default_value_ && command_line_->HasSwitch(GetLegacyEnableFlag())) |
191 return true; | 227 return true; |
192 | 228 |
193 if (default_value_ && command_line_->HasSwitch(GetLegacyDisableFlag())) | 229 if (default_value_ && command_line_->HasSwitch(GetLegacyDisableFlag())) |
194 return false; | 230 return false; |
195 | 231 |
196 if (field_trial_name_) { | 232 if (!required_field_trials_.empty()) { |
197 std::string group_name = | 233 bool enabled_by_field_trial = true; |
198 base::FieldTrialList::FindFullName(field_trial_name_); | 234 bool disabled_by_field_trial = false; |
199 if (group_name == "Enabled") | 235 for (const std::string& field_trial_name : required_field_trials_) { |
236 std::string group_name = | |
237 base::FieldTrialList::FindFullName(field_trial_name); | |
238 if (group_name != "Enabled") { | |
239 enabled_by_field_trial = false; | |
240 } | |
241 if (group_name == "Disabled") { | |
Devlin
2016/02/10 21:52:06
nit: Might as well nest this inside the above if.
imcheng
2016/02/10 21:57:42
Done.
| |
242 disabled_by_field_trial = true; | |
243 break; | |
244 } | |
245 } | |
246 if (disabled_by_field_trial) | |
247 return false; | |
248 if (enabled_by_field_trial) | |
200 return true; | 249 return true; |
201 if (group_name == "Disabled") | |
202 return false; | |
203 } | 250 } |
204 | 251 |
205 return default_value_; | 252 return default_value_; |
206 } | 253 } |
207 | 254 |
208 std::string FeatureSwitch::GetLegacyEnableFlag() const { | 255 std::string FeatureSwitch::GetLegacyEnableFlag() const { |
209 DCHECK(switch_name_); | 256 DCHECK(switch_name_); |
210 return std::string("enable-") + switch_name_; | 257 return std::string("enable-") + switch_name_; |
211 } | 258 } |
212 | 259 |
213 std::string FeatureSwitch::GetLegacyDisableFlag() const { | 260 std::string FeatureSwitch::GetLegacyDisableFlag() const { |
214 DCHECK(switch_name_); | 261 DCHECK(switch_name_); |
215 return std::string("disable-") + switch_name_; | 262 return std::string("disable-") + switch_name_; |
216 } | 263 } |
217 | 264 |
218 void FeatureSwitch::SetOverrideValue(OverrideValue override_value) { | 265 void FeatureSwitch::SetOverrideValue(OverrideValue override_value) { |
219 override_value_ = override_value; | 266 override_value_ = override_value; |
220 } | 267 } |
221 | 268 |
222 FeatureSwitch::OverrideValue FeatureSwitch::GetOverrideValue() const { | 269 FeatureSwitch::OverrideValue FeatureSwitch::GetOverrideValue() const { |
223 return override_value_; | 270 return override_value_; |
224 } | 271 } |
225 | 272 |
226 } // namespace extensions | 273 } // namespace extensions |
OLD | NEW |