Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: components/flags_ui/flags_state.cc

Issue 2036193002: Allow overriding variation parameter via chrome://flags. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Build deps #2 Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/flags_ui/flags_state.h ('k') | components/flags_ui/flags_state_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/flags_ui/flags_state.h" 5 #include "components/flags_ui/flags_state.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/feature_list.h" 11 #include "base/feature_list.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h"
14 #include "base/stl_util.h" 15 #include "base/stl_util.h"
15 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h" 18 #include "base/values.h"
18 #include "build/build_config.h" 19 #include "build/build_config.h"
19 #include "components/flags_ui/feature_entry.h" 20 #include "components/flags_ui/feature_entry.h"
20 #include "components/flags_ui/flags_storage.h" 21 #include "components/flags_ui/flags_storage.h"
21 #include "components/flags_ui/flags_ui_switches.h" 22 #include "components/flags_ui/flags_ui_switches.h"
23 #include "components/variations/variations_associated_data.h"
22 #include "ui/base/l10n/l10n_util.h" 24 #include "ui/base/l10n/l10n_util.h"
23 25
24 namespace flags_ui { 26 namespace flags_ui {
25 27
28 namespace internal {
29 const char kTrialGroupAboutFlags[] = "AboutFlags";
30 } // namespace internal
31
26 namespace { 32 namespace {
27 33
28 // Convert switch constants to proper CommandLine::StringType strings. 34 // Convert switch constants to proper CommandLine::StringType strings.
29 base::CommandLine::StringType GetSwitchString(const std::string& flag) { 35 base::CommandLine::StringType GetSwitchString(const std::string& flag) {
30 base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM); 36 base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
31 cmd_line.AppendSwitch(flag); 37 cmd_line.AppendSwitch(flag);
32 DCHECK_EQ(2U, cmd_line.argv().size()); 38 DCHECK_EQ(2U, cmd_line.argv().size());
33 return cmd_line.argv()[1]; 39 return cmd_line.argv()[1];
34 } 40 }
35 41
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Adds the internal names for the specified entry to |names|. 98 // Adds the internal names for the specified entry to |names|.
93 void AddInternalName(const FeatureEntry& e, std::set<std::string>* names) { 99 void AddInternalName(const FeatureEntry& e, std::set<std::string>* names) {
94 switch (e.type) { 100 switch (e.type) {
95 case FeatureEntry::SINGLE_VALUE: 101 case FeatureEntry::SINGLE_VALUE:
96 case FeatureEntry::SINGLE_DISABLE_VALUE: 102 case FeatureEntry::SINGLE_DISABLE_VALUE:
97 names->insert(e.internal_name); 103 names->insert(e.internal_name);
98 break; 104 break;
99 case FeatureEntry::MULTI_VALUE: 105 case FeatureEntry::MULTI_VALUE:
100 case FeatureEntry::ENABLE_DISABLE_VALUE: 106 case FeatureEntry::ENABLE_DISABLE_VALUE:
101 case FeatureEntry::FEATURE_VALUE: 107 case FeatureEntry::FEATURE_VALUE:
102 for (int i = 0; i < e.num_choices; ++i) 108 case FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE:
103 names->insert(e.NameForChoice(i)); 109 for (int i = 0; i < e.num_options; ++i)
110 names->insert(e.NameForOption(i));
104 break; 111 break;
105 } 112 }
106 } 113 }
107 114
108 // Confirms that an entry is valid, used in a DCHECK in 115 // Confirms that an entry is valid, used in a DCHECK in
109 // SanitizeList below. 116 // SanitizeList below.
110 bool ValidateFeatureEntry(const FeatureEntry& e) { 117 bool ValidateFeatureEntry(const FeatureEntry& e) {
111 switch (e.type) { 118 switch (e.type) {
112 case FeatureEntry::SINGLE_VALUE: 119 case FeatureEntry::SINGLE_VALUE:
113 case FeatureEntry::SINGLE_DISABLE_VALUE: 120 case FeatureEntry::SINGLE_DISABLE_VALUE:
114 DCHECK_EQ(0, e.num_choices); 121 DCHECK_EQ(0, e.num_options);
115 DCHECK(!e.choices); 122 DCHECK(!e.choices);
116 return true; 123 return true;
117 case FeatureEntry::MULTI_VALUE: 124 case FeatureEntry::MULTI_VALUE:
118 DCHECK_GT(e.num_choices, 0); 125 DCHECK_GT(e.num_options, 0);
119 DCHECK(e.choices); 126 DCHECK(e.choices);
120 DCHECK(e.choices[0].command_line_switch); 127 DCHECK(e.ChoiceForOption(0).command_line_switch);
121 DCHECK_EQ('\0', e.choices[0].command_line_switch[0]); 128 DCHECK_EQ('\0', e.ChoiceForOption(0).command_line_switch[0]);
122 return true; 129 return true;
123 case FeatureEntry::ENABLE_DISABLE_VALUE: 130 case FeatureEntry::ENABLE_DISABLE_VALUE:
124 DCHECK_EQ(3, e.num_choices); 131 DCHECK_EQ(3, e.num_options);
125 DCHECK(!e.choices); 132 DCHECK(!e.choices);
126 DCHECK(e.command_line_switch); 133 DCHECK(e.command_line_switch);
127 DCHECK(e.command_line_value); 134 DCHECK(e.command_line_value);
128 DCHECK(e.disable_command_line_switch); 135 DCHECK(e.disable_command_line_switch);
129 DCHECK(e.disable_command_line_value); 136 DCHECK(e.disable_command_line_value);
130 return true; 137 return true;
131 case FeatureEntry::FEATURE_VALUE: 138 case FeatureEntry::FEATURE_VALUE:
132 DCHECK_EQ(3, e.num_choices); 139 DCHECK_EQ(3, e.num_options);
133 DCHECK(!e.choices); 140 DCHECK(!e.choices);
134 DCHECK(e.feature); 141 DCHECK(e.feature);
135 return true; 142 return true;
143 case FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE:
144 DCHECK_GT(e.num_options, 2);
145 DCHECK(!e.choices);
146 DCHECK(e.feature);
147 DCHECK(e.feature_variations);
148 DCHECK(e.feature_trial_name);
149 return true;
136 } 150 }
137 NOTREACHED(); 151 NOTREACHED();
138 return false; 152 return false;
139 } 153 }
140 154
141 // Returns true if none of this entry's options have been enabled. 155 // Returns true if none of this entry's options have been enabled.
142 bool IsDefaultValue(const FeatureEntry& entry, 156 bool IsDefaultValue(const FeatureEntry& entry,
143 const std::set<std::string>& enabled_entries) { 157 const std::set<std::string>& enabled_entries) {
144 switch (entry.type) { 158 switch (entry.type) {
145 case FeatureEntry::SINGLE_VALUE: 159 case FeatureEntry::SINGLE_VALUE:
146 case FeatureEntry::SINGLE_DISABLE_VALUE: 160 case FeatureEntry::SINGLE_DISABLE_VALUE:
147 return enabled_entries.count(entry.internal_name) == 0; 161 return enabled_entries.count(entry.internal_name) == 0;
148 case FeatureEntry::MULTI_VALUE: 162 case FeatureEntry::MULTI_VALUE:
149 case FeatureEntry::ENABLE_DISABLE_VALUE: 163 case FeatureEntry::ENABLE_DISABLE_VALUE:
150 case FeatureEntry::FEATURE_VALUE: 164 case FeatureEntry::FEATURE_VALUE:
151 for (int i = 0; i < entry.num_choices; ++i) { 165 case FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE:
152 if (enabled_entries.count(entry.NameForChoice(i)) > 0) 166 for (int i = 0; i < entry.num_options; ++i) {
167 if (enabled_entries.count(entry.NameForOption(i)) > 0)
153 return false; 168 return false;
154 } 169 }
155 return true; 170 return true;
156 } 171 }
157 NOTREACHED(); 172 NOTREACHED();
158 return true; 173 return true;
159 } 174 }
160 175
161 // Returns the Value representing the choice data in the specified entry. 176 // Returns the Value representing the choice data in the specified entry.
162 base::Value* CreateChoiceData(const FeatureEntry& entry, 177 base::Value* CreateOptionsData(const FeatureEntry& entry,
163 const std::set<std::string>& enabled_entries) { 178 const std::set<std::string>& enabled_entries) {
164 DCHECK(entry.type == FeatureEntry::MULTI_VALUE || 179 DCHECK(entry.type == FeatureEntry::MULTI_VALUE ||
165 entry.type == FeatureEntry::ENABLE_DISABLE_VALUE || 180 entry.type == FeatureEntry::ENABLE_DISABLE_VALUE ||
166 entry.type == FeatureEntry::FEATURE_VALUE); 181 entry.type == FeatureEntry::FEATURE_VALUE ||
182 entry.type == FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE);
167 base::ListValue* result = new base::ListValue; 183 base::ListValue* result = new base::ListValue;
168 for (int i = 0; i < entry.num_choices; ++i) { 184 for (int i = 0; i < entry.num_options; ++i) {
169 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); 185 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
170 const std::string name = entry.NameForChoice(i); 186 const std::string name = entry.NameForOption(i);
171 value->SetString("internal_name", name); 187 value->SetString("internal_name", name);
172 value->SetString("description", entry.DescriptionForChoice(i)); 188 value->SetString("description", entry.DescriptionForOption(i));
173 value->SetBoolean("selected", enabled_entries.count(name) > 0); 189 value->SetBoolean("selected", enabled_entries.count(name) > 0);
174 result->Append(std::move(value)); 190 result->Append(std::move(value));
175 } 191 }
176 return result; 192 return result;
177 } 193 }
178 194
195 // Registers variation parameters specified by |feature_variation| for the field
196 // trial named |feature_trial_name|, unless a group for this trial has already
197 // been created (e.g. via command-line switches that take precedence over
198 // about:flags). In the trial, the function creates a new constant group called
199 // |kTrialGroupAboutFlags|.
200 void RegisterFeatureVariationParameters(
201 const std::string& feature_trial_name,
202 const FeatureEntry::FeatureVariation& feature_variation) {
203 std::map<std::string, std::string> params;
204 for (int i = 0; i < feature_variation.num_params; ++i) {
205 params[feature_variation.params[i].param_name] =
206 feature_variation.params[i].param_value;
207 }
208
209 bool success = variations::AssociateVariationParams(
210 feature_trial_name, internal::kTrialGroupAboutFlags, params);
211 if (success) {
212 // Successful association also means that no group is created and selected
213 // for the trial, yet. Thus, create the trial to select the group. This way,
214 // the parameters cannot get overwritten in later phases (such as from the
215 // server).
216 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
217 feature_trial_name, internal::kTrialGroupAboutFlags);
218 if (!trial) {
219 DLOG(WARNING) << "Could not create the trial " << feature_trial_name
220 << " with group " << internal::kTrialGroupAboutFlags;
221 }
222 }
223 }
224
179 } // namespace 225 } // namespace
180 226
181 // Keeps track of affected switches for each FeatureEntry, based on which 227 // Keeps track of affected switches for each FeatureEntry, based on which
182 // choice is selected for it. 228 // choice is selected for it.
183 struct SwitchEntry { 229 struct SwitchEntry {
184 // Corresponding base::Feature to toggle. 230 // Corresponding base::Feature to toggle.
185 std::string feature_name; 231 std::string feature_name;
186 232
187 // If |feature_name| is not empty, the state (enable/disabled) to set. 233 // If |feature_name| is not empty, the state (enable/disabled) to set.
188 bool feature_state; 234 bool feature_state;
(...skipping 28 matching lines...) Expand all
217 std::map<std::string, SwitchEntry> name_to_switch_map; 263 std::map<std::string, SwitchEntry> name_to_switch_map;
218 for (size_t i = 0; i < num_feature_entries_; ++i) { 264 for (size_t i = 0; i < num_feature_entries_; ++i) {
219 const FeatureEntry& e = feature_entries_[i]; 265 const FeatureEntry& e = feature_entries_[i];
220 switch (e.type) { 266 switch (e.type) {
221 case FeatureEntry::SINGLE_VALUE: 267 case FeatureEntry::SINGLE_VALUE:
222 case FeatureEntry::SINGLE_DISABLE_VALUE: 268 case FeatureEntry::SINGLE_DISABLE_VALUE:
223 AddSwitchMapping(e.internal_name, e.command_line_switch, 269 AddSwitchMapping(e.internal_name, e.command_line_switch,
224 e.command_line_value, &name_to_switch_map); 270 e.command_line_value, &name_to_switch_map);
225 break; 271 break;
226 case FeatureEntry::MULTI_VALUE: 272 case FeatureEntry::MULTI_VALUE:
227 for (int j = 0; j < e.num_choices; ++j) { 273 for (int j = 0; j < e.num_options; ++j) {
228 AddSwitchMapping(e.NameForChoice(j), e.choices[j].command_line_switch, 274 AddSwitchMapping(
229 e.choices[j].command_line_value, 275 e.NameForOption(j), e.ChoiceForOption(j).command_line_switch,
230 &name_to_switch_map); 276 e.ChoiceForOption(j).command_line_value, &name_to_switch_map);
231 } 277 }
232 break; 278 break;
233 case FeatureEntry::ENABLE_DISABLE_VALUE: 279 case FeatureEntry::ENABLE_DISABLE_VALUE:
234 AddSwitchMapping(e.NameForChoice(0), std::string(), std::string(), 280 AddSwitchMapping(e.NameForOption(0), std::string(), std::string(),
235 &name_to_switch_map); 281 &name_to_switch_map);
236 AddSwitchMapping(e.NameForChoice(1), e.command_line_switch, 282 AddSwitchMapping(e.NameForOption(1), e.command_line_switch,
237 e.command_line_value, &name_to_switch_map); 283 e.command_line_value, &name_to_switch_map);
238 AddSwitchMapping(e.NameForChoice(2), e.disable_command_line_switch, 284 AddSwitchMapping(e.NameForOption(2), e.disable_command_line_switch,
239 e.disable_command_line_value, &name_to_switch_map); 285 e.disable_command_line_value, &name_to_switch_map);
240 break; 286 break;
241 case FeatureEntry::FEATURE_VALUE: 287 case FeatureEntry::FEATURE_VALUE:
242 AddFeatureMapping(e.NameForChoice(0), std::string(), false, 288 case FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE:
243 &name_to_switch_map); 289 for (int j = 0; j < e.num_options; ++j) {
244 AddFeatureMapping(e.NameForChoice(1), e.feature->name, true, 290 FeatureEntry::FeatureState state = e.StateForOption(j);
245 &name_to_switch_map); 291 if (state == FeatureEntry::FeatureState::DEFAULT) {
246 AddFeatureMapping(e.NameForChoice(2), e.feature->name, false, 292 AddFeatureMapping(e.NameForOption(j), std::string(), false,
247 &name_to_switch_map); 293 &name_to_switch_map);
294 } else {
295 AddFeatureMapping(e.NameForOption(j), e.feature->name,
296 state == FeatureEntry::FeatureState::ENABLED,
297 &name_to_switch_map);
298 }
299 }
248 break; 300 break;
249 } 301 }
250 } 302 }
251 303
252 AddSwitchesToCommandLine(enabled_entries, name_to_switch_map, sentinels, 304 AddSwitchesToCommandLine(enabled_entries, name_to_switch_map, sentinels,
253 command_line, enable_features_flag_name, 305 command_line, enable_features_flag_name,
254 disable_features_flag_name); 306 disable_features_flag_name);
255 } 307 }
256 308
257 bool FlagsState::IsRestartNeededToCommitChanges() { 309 bool FlagsState::IsRestartNeededToCommitChanges() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 else 350 else
299 needs_restart_ |= (enabled_entries.erase(internal_name) > 0); 351 needs_restart_ |= (enabled_entries.erase(internal_name) > 0);
300 } else if (e->type == FeatureEntry::SINGLE_DISABLE_VALUE) { 352 } else if (e->type == FeatureEntry::SINGLE_DISABLE_VALUE) {
301 if (!enable) 353 if (!enable)
302 needs_restart_ |= enabled_entries.insert(internal_name).second; 354 needs_restart_ |= enabled_entries.insert(internal_name).second;
303 else 355 else
304 needs_restart_ |= (enabled_entries.erase(internal_name) > 0); 356 needs_restart_ |= (enabled_entries.erase(internal_name) > 0);
305 } else { 357 } else {
306 if (enable) { 358 if (enable) {
307 // Enable the first choice. 359 // Enable the first choice.
308 needs_restart_ |= enabled_entries.insert(e->NameForChoice(0)).second; 360 needs_restart_ |= enabled_entries.insert(e->NameForOption(0)).second;
309 } else { 361 } else {
310 // Find the currently enabled choice and disable it. 362 // Find the currently enabled choice and disable it.
311 for (int i = 0; i < e->num_choices; ++i) { 363 for (int i = 0; i < e->num_options; ++i) {
312 std::string choice_name = e->NameForChoice(i); 364 std::string choice_name = e->NameForOption(i);
313 if (enabled_entries.find(choice_name) != enabled_entries.end()) { 365 if (enabled_entries.find(choice_name) != enabled_entries.end()) {
314 needs_restart_ = true; 366 needs_restart_ = true;
315 enabled_entries.erase(choice_name); 367 enabled_entries.erase(choice_name);
316 // Continue on just in case there's a bug and more than one 368 // Continue on just in case there's a bug and more than one
317 // entry for this choice was enabled. 369 // entry for this choice was enabled.
318 } 370 }
319 } 371 }
320 } 372 }
321 } 373 }
322 374
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 std::set<std::string> no_entries; 425 std::set<std::string> no_entries;
374 flags_storage->SetFlags(no_entries); 426 flags_storage->SetFlags(no_entries);
375 } 427 }
376 428
377 void FlagsState::Reset() { 429 void FlagsState::Reset() {
378 needs_restart_ = false; 430 needs_restart_ = false;
379 flags_switches_.clear(); 431 flags_switches_.clear();
380 appended_switches_.clear(); 432 appended_switches_.clear();
381 } 433 }
382 434
435 void FlagsState::RegisterAllFeatureVariationParameters(
436 FlagsStorage* flags_storage) {
437 std::set<std::string> enabled_entries;
438 GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries);
439
440 for (size_t i = 0; i < num_feature_entries_; ++i) {
441 const FeatureEntry& e = feature_entries_[i];
442 if (e.type == FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE) {
443 for (int j = 0; j < e.num_options; ++j) {
444 const FeatureEntry::FeatureVariation* variation =
445 e.VariationForOption(j);
446 if (variation != nullptr && enabled_entries.count(e.NameForOption(j))) {
447 // If the option is selected by the user & has variation, register it.
448 RegisterFeatureVariationParameters(e.feature_trial_name, *variation);
449 // TODO(jkrcal) The code does not associate the feature with the field
450 // trial |e.feature_trial_name|. The reason is that features
451 // overridden in chrome://flags are translated to command-line flags
452 // and thus treated earlier in the initialization. The fix requires
453 // larger changes. As a result:
454 // - the API calls to variations::GetVariationParamValueByFeature and
455 // to variations::GetVariationParamsByFeature do not work; and
456 // - the API call to base::FeatureList::IsEnabled does not mark the
457 // field trial as active (and the trial does not appear in UMA).
458 // If the code calls variations::GetVariationParamValue or
459 // variations::GetVariationParams providing the trial name, everything
460 // should work fine.
461 }
462 }
463 }
464 }
465 }
466
383 void FlagsState::GetFlagFeatureEntries( 467 void FlagsState::GetFlagFeatureEntries(
384 FlagsStorage* flags_storage, 468 FlagsStorage* flags_storage,
385 FlagAccess access, 469 FlagAccess access,
386 base::ListValue* supported_entries, 470 base::ListValue* supported_entries,
387 base::ListValue* unsupported_entries, 471 base::ListValue* unsupported_entries,
388 base::Callback<bool(const FeatureEntry&)> skip_feature_entry) { 472 base::Callback<bool(const FeatureEntry&)> skip_feature_entry) {
389 std::set<std::string> enabled_entries; 473 std::set<std::string> enabled_entries;
390 GetSanitizedEnabledFlags(flags_storage, &enabled_entries); 474 GetSanitizedEnabledFlags(flags_storage, &enabled_entries);
391 475
392 int current_platform = GetCurrentPlatform(); 476 int current_platform = GetCurrentPlatform();
(...skipping 21 matching lines...) Expand all
414 case FeatureEntry::SINGLE_DISABLE_VALUE: 498 case FeatureEntry::SINGLE_DISABLE_VALUE:
415 data->SetBoolean( 499 data->SetBoolean(
416 "enabled", 500 "enabled",
417 (!is_default_value && entry.type == FeatureEntry::SINGLE_VALUE) || 501 (!is_default_value && entry.type == FeatureEntry::SINGLE_VALUE) ||
418 (is_default_value && 502 (is_default_value &&
419 entry.type == FeatureEntry::SINGLE_DISABLE_VALUE)); 503 entry.type == FeatureEntry::SINGLE_DISABLE_VALUE));
420 break; 504 break;
421 case FeatureEntry::MULTI_VALUE: 505 case FeatureEntry::MULTI_VALUE:
422 case FeatureEntry::ENABLE_DISABLE_VALUE: 506 case FeatureEntry::ENABLE_DISABLE_VALUE:
423 case FeatureEntry::FEATURE_VALUE: 507 case FeatureEntry::FEATURE_VALUE:
424 data->Set("choices", CreateChoiceData(entry, enabled_entries)); 508 case FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE:
509 data->Set("options", CreateOptionsData(entry, enabled_entries));
425 break; 510 break;
426 } 511 }
427 512
428 bool supported = (entry.supported_platforms & current_platform) != 0; 513 bool supported = (entry.supported_platforms & current_platform) != 0;
429 #if defined(OS_CHROMEOS) 514 #if defined(OS_CHROMEOS)
430 if (access == kOwnerAccessToFlags && 515 if (access == kOwnerAccessToFlags &&
431 (entry.supported_platforms & kOsCrOSOwnerOnly) != 0) { 516 (entry.supported_platforms & kOsCrOSOwnerOnly) != 0) {
432 supported = true; 517 supported = true;
433 } 518 }
434 #endif 519 #endif
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 } 719 }
635 720
636 std::set<std::string> new_enabled_entries = 721 std::set<std::string> new_enabled_entries =
637 base::STLSetIntersection<std::set<std::string>>(platform_entries, 722 base::STLSetIntersection<std::set<std::string>>(platform_entries,
638 *result); 723 *result);
639 724
640 result->swap(new_enabled_entries); 725 result->swap(new_enabled_entries);
641 } 726 }
642 727
643 } // namespace flags_ui 728 } // namespace flags_ui
OLDNEW
« no previous file with comments | « components/flags_ui/flags_state.h ('k') | components/flags_ui/flags_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698