| OLD | NEW |
| 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" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); | 185 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); |
| 186 const std::string name = entry.NameForOption(i); | 186 const std::string name = entry.NameForOption(i); |
| 187 value->SetString("internal_name", name); | 187 value->SetString("internal_name", name); |
| 188 value->SetString("description", entry.DescriptionForOption(i)); | 188 value->SetString("description", entry.DescriptionForOption(i)); |
| 189 value->SetBoolean("selected", enabled_entries.count(name) > 0); | 189 value->SetBoolean("selected", enabled_entries.count(name) > 0); |
| 190 result->Append(std::move(value)); | 190 result->Append(std::move(value)); |
| 191 } | 191 } |
| 192 return result; | 192 return result; |
| 193 } | 193 } |
| 194 | 194 |
| 195 // Registers variation parameters specified by |feature_variation| for the field | 195 // Registers variation parameters specified by |feature_variation_params| for |
| 196 // trial named |feature_trial_name|, unless a group for this trial has already | 196 // the field trial named |feature_trial_name|, unless a group for this trial has |
| 197 // been created (e.g. via command-line switches that take precedence over | 197 // already been created (e.g. via command-line switches that take precedence |
| 198 // about:flags). In the trial, the function creates a new constant group called | 198 // over about:flags). In the trial, the function creates a new constant group |
| 199 // |kTrialGroupAboutFlags|. | 199 // called |kTrialGroupAboutFlags|. |
| 200 base::FieldTrial* RegisterFeatureVariationParameters( | 200 base::FieldTrial* RegisterFeatureVariationParameters( |
| 201 const std::string& feature_trial_name, | 201 const std::string& feature_trial_name, |
| 202 const FeatureEntry::FeatureVariation* feature_variation) { | 202 const std::map<std::string, std::string>& feature_variation_params) { |
| 203 std::map<std::string, std::string> params; | |
| 204 if (feature_variation) { | |
| 205 // Copy the parameters for non-null variations. | |
| 206 for (int i = 0; i < feature_variation->num_params; ++i) { | |
| 207 params[feature_variation->params[i].param_name] = | |
| 208 feature_variation->params[i].param_value; | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 bool success = variations::AssociateVariationParams( | 203 bool success = variations::AssociateVariationParams( |
| 213 feature_trial_name, internal::kTrialGroupAboutFlags, params); | 204 feature_trial_name, internal::kTrialGroupAboutFlags, |
| 205 feature_variation_params); |
| 214 if (!success) | 206 if (!success) |
| 215 return nullptr; | 207 return nullptr; |
| 216 // Successful association also means that no group is created and selected | 208 // Successful association also means that no group is created and selected |
| 217 // for the trial, yet. Thus, create the trial to select the group. This way, | 209 // for the trial, yet. Thus, create the trial to select the group. This way, |
| 218 // the parameters cannot get overwritten in later phases (such as from the | 210 // the parameters cannot get overwritten in later phases (such as from the |
| 219 // server). | 211 // server). |
| 220 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( | 212 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( |
| 221 feature_trial_name, internal::kTrialGroupAboutFlags); | 213 feature_trial_name, internal::kTrialGroupAboutFlags); |
| 222 if (!trial) { | 214 if (!trial) { |
| 223 DLOG(WARNING) << "Could not create the trial " << feature_trial_name | 215 DLOG(WARNING) << "Could not create the trial " << feature_trial_name |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 flags_switches_.clear(); | 426 flags_switches_.clear(); |
| 435 appended_switches_.clear(); | 427 appended_switches_.clear(); |
| 436 } | 428 } |
| 437 | 429 |
| 438 std::vector<std::string> FlagsState::RegisterAllFeatureVariationParameters( | 430 std::vector<std::string> FlagsState::RegisterAllFeatureVariationParameters( |
| 439 FlagsStorage* flags_storage, | 431 FlagsStorage* flags_storage, |
| 440 base::FeatureList* feature_list) { | 432 base::FeatureList* feature_list) { |
| 441 std::set<std::string> enabled_entries; | 433 std::set<std::string> enabled_entries; |
| 442 GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries); | 434 GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries); |
| 443 std::vector<std::string> variation_ids; | 435 std::vector<std::string> variation_ids; |
| 436 std::map<std::string, std::set<std::string>> enabled_features_by_trial_name; |
| 437 std::map<std::string, std::map<std::string, std::string>> |
| 438 params_by_trial_name; |
| 444 | 439 |
| 440 // First collect all the data for each trial. |
| 445 for (size_t i = 0; i < num_feature_entries_; ++i) { | 441 for (size_t i = 0; i < num_feature_entries_; ++i) { |
| 446 const FeatureEntry& e = feature_entries_[i]; | 442 const FeatureEntry& e = feature_entries_[i]; |
| 447 if (e.type == FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE) { | 443 if (e.type == FeatureEntry::FEATURE_WITH_VARIATIONS_VALUE) { |
| 448 for (int j = 0; j < e.num_options; ++j) { | 444 for (int j = 0; j < e.num_options; ++j) { |
| 449 const FeatureEntry::FeatureVariation* variation = | |
| 450 e.VariationForOption(j); | |
| 451 if (e.StateForOption(j) == FeatureEntry::FeatureState::ENABLED && | 445 if (e.StateForOption(j) == FeatureEntry::FeatureState::ENABLED && |
| 452 enabled_entries.count(e.NameForOption(j))) { | 446 enabled_entries.count(e.NameForOption(j))) { |
| 453 // If the option is selected by the user & has variation, register it. | 447 std::string trial_name = e.feature_trial_name; |
| 454 base::FieldTrial* field_trial = RegisterFeatureVariationParameters( | 448 // The user has chosen to enable the feature by this option. |
| 455 e.feature_trial_name, variation); | 449 enabled_features_by_trial_name[trial_name].insert(e.feature->name); |
| 456 | 450 |
| 457 if (!field_trial) | 451 const FeatureEntry::FeatureVariation* variation = |
| 452 e.VariationForOption(j); |
| 453 if (!variation) |
| 458 continue; | 454 continue; |
| 459 feature_list->RegisterFieldTrialOverride( | |
| 460 e.feature->name, | |
| 461 base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE, | |
| 462 field_trial); | |
| 463 | 455 |
| 464 if (variation && variation->variation_id) | 456 // The selected variation is non-default, collect its params & id. |
| 457 |
| 458 for (int i = 0; i < variation->num_params; ++i) { |
| 459 auto insert_result = params_by_trial_name[trial_name].insert( |
| 460 std::make_pair(variation->params[i].param_name, |
| 461 variation->params[i].param_value)); |
| 462 DCHECK(insert_result.second) |
| 463 << "Multiple values for the same parameter '" |
| 464 << variation->params[i].param_name |
| 465 << "' are specified in chrome://flags!"; |
| 466 } |
| 467 if (variation->variation_id) |
| 465 variation_ids.push_back(variation->variation_id); | 468 variation_ids.push_back(variation->variation_id); |
| 466 } | 469 } |
| 467 } | 470 } |
| 468 } | 471 } |
| 469 } | 472 } |
| 473 |
| 474 // Now create the trials and associate the features to them. |
| 475 for (const auto& kv : enabled_features_by_trial_name) { |
| 476 const std::string& trial_name = kv.first; |
| 477 const std::set<std::string>& trial_features = kv.second; |
| 478 |
| 479 base::FieldTrial* field_trial = RegisterFeatureVariationParameters( |
| 480 trial_name, params_by_trial_name[trial_name]); |
| 481 if (!field_trial) |
| 482 continue; |
| 483 |
| 484 for (const std::string& feature_name : trial_features) { |
| 485 feature_list->RegisterFieldTrialOverride( |
| 486 feature_name, |
| 487 base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE, |
| 488 field_trial); |
| 489 } |
| 490 } |
| 491 |
| 470 return variation_ids; | 492 return variation_ids; |
| 471 } | 493 } |
| 472 | 494 |
| 473 void FlagsState::GetFlagFeatureEntries( | 495 void FlagsState::GetFlagFeatureEntries( |
| 474 FlagsStorage* flags_storage, | 496 FlagsStorage* flags_storage, |
| 475 FlagAccess access, | 497 FlagAccess access, |
| 476 base::ListValue* supported_entries, | 498 base::ListValue* supported_entries, |
| 477 base::ListValue* unsupported_entries, | 499 base::ListValue* unsupported_entries, |
| 478 base::Callback<bool(const FeatureEntry&)> skip_feature_entry) { | 500 base::Callback<bool(const FeatureEntry&)> skip_feature_entry) { |
| 479 std::set<std::string> enabled_entries; | 501 std::set<std::string> enabled_entries; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 state == FeatureEntry::FeatureState::ENABLED, | 794 state == FeatureEntry::FeatureState::ENABLED, |
| 773 name_to_switch_map); | 795 name_to_switch_map); |
| 774 } | 796 } |
| 775 } | 797 } |
| 776 break; | 798 break; |
| 777 } | 799 } |
| 778 } | 800 } |
| 779 } | 801 } |
| 780 | 802 |
| 781 } // namespace flags_ui | 803 } // namespace flags_ui |
| OLD | NEW |