summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorasvitkine <asvitkine@chromium.org>2016-03-22 08:37:52 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-22 15:39:07 +0000
commit6d31c52edc9c6d20419b6fe12f66c60548ab7142 (patch)
treee9cc8f9a5cac0a8a733b85af5ca1cb8cf7532ad3 /base
parent866b9e1c3542ed922285cf06b7d60f89758b20b5 (diff)
downloadchromium_src-6d31c52edc9c6d20419b6fe12f66c60548ab7142.zip
chromium_src-6d31c52edc9c6d20419b6fe12f66c60548ab7142.tar.gz
chromium_src-6d31c52edc9c6d20419b6fe12f66c60548ab7142.tar.bz2
Plumb trial association without overriding a feature to subprocesses.
This makes features used in only in renders report their default group correctly as well. This is done by having the --enable-features flag also plumb the non-overriding associations over. This way, when a feature is queried in the renderer, the associated trial is activated there (and then synced to the browser). BUG=587135 Review URL: https://codereview.chromium.org/1824753002 Cr-Commit-Position: refs/heads/master@{#382575}
Diffstat (limited to 'base')
-rw-r--r--base/feature_list.cc14
-rw-r--r--base/feature_list.h12
-rw-r--r--base/feature_list_unittest.cc39
3 files changed, 58 insertions, 7 deletions
diff --git a/base/feature_list.cc b/base/feature_list.cc
index 089da64..853fc4d 100644
--- a/base/feature_list.cc
+++ b/base/feature_list.cc
@@ -30,7 +30,7 @@ FeatureList* g_instance = nullptr;
// are any reserved characters present, returning true if the string is valid.
// Only called in DCHECKs.
bool IsValidFeatureOrFieldTrialName(const std::string& name) {
- return IsStringASCII(name) && name.find_first_of(",<") == std::string::npos;
+ return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos;
}
} // namespace
@@ -99,21 +99,25 @@ void FeatureList::GetFeatureOverrides(std::string* enable_overrides,
enable_overrides->clear();
disable_overrides->clear();
+ // Note: Since |overrides_| is a std::map, iteration will be in alphabetical
+ // order. This not guaranteed to users of this function, but is useful for
+ // tests to assume the order.
for (const auto& entry : overrides_) {
std::string* target_list = nullptr;
switch (entry.second.overridden_state) {
+ case OVERRIDE_USE_DEFAULT:
case OVERRIDE_ENABLE_FEATURE:
target_list = enable_overrides;
break;
case OVERRIDE_DISABLE_FEATURE:
target_list = disable_overrides;
break;
- case OVERRIDE_USE_DEFAULT:
- continue;
}
if (!target_list->empty())
target_list->push_back(',');
+ if (entry.second.overridden_state == OVERRIDE_USE_DEFAULT)
+ target_list->push_back('*');
target_list->append(entry.first);
if (entry.second.field_trial) {
target_list->push_back('<');
@@ -215,6 +219,10 @@ void FeatureList::RegisterOverride(StringPiece feature_name,
DCHECK(IsValidFeatureOrFieldTrialName(field_trial->trial_name()))
<< field_trial->trial_name();
}
+ if (feature_name.starts_with("*")) {
+ feature_name = feature_name.substr(1);
+ overridden_state = OVERRIDE_USE_DEFAULT;
+ }
// Note: The semantics of insert() is that it does not overwrite the entry if
// one already exists for the key. Thus, only the first override for a given
diff --git a/base/feature_list.h b/base/feature_list.h
index 90128cf..cf865a1 100644
--- a/base/feature_list.h
+++ b/base/feature_list.h
@@ -84,8 +84,11 @@ class BASE_EXPORT FeatureList {
// enable or disable, respectively. If a feature appears on both lists, then
// it will be disabled. If a list entry has the format "FeatureName<TrialName"
// then this initialization will also associate the feature state override
- // with the named field trial, if it exists. Must only be invoked during the
- // initialization phase (before FinalizeInitialization() has been called).
+ // with the named field trial, if it exists. If a feature name is prefixed
+ // with the '*' character, it will be created with OVERRIDE_USE_DEFAULT -
+ // which is useful for associating with a trial while using the default state.
+ // Must only be invoked during the initialization phase (before
+ // FinalizeInitialization() has been called).
void InitializeFromCommandLine(const std::string& enable_features,
const std::string& disable_features);
@@ -126,8 +129,9 @@ class BASE_EXPORT FeatureList {
// have been overridden - either through command-line or via FieldTrials. For
// those features that have an associated FieldTrial, the output entry will be
// of the format "FeatureName<TrialName", where "TrialName" is the name of the
- // FieldTrial. Must be called only after the instance has been initialized and
- // registered.
+ // FieldTrial. Features that have overrides with OVERRIDE_USE_DEFAULT will be
+ // added to |enable_overrides| with a '*' character prefix. Must be called
+ // only after the instance has been initialized and registered.
void GetFeatureOverrides(std::string* enable_overrides,
std::string* disable_overrides);
diff --git a/base/feature_list_unittest.cc b/base/feature_list_unittest.cc
index 7155e86..038913d 100644
--- a/base/feature_list_unittest.cc
+++ b/base/feature_list_unittest.cc
@@ -372,6 +372,26 @@ TEST_F(FeatureListTest, GetFeatureOverrides) {
EXPECT_EQ("D", SortFeatureListString(disable_features));
}
+TEST_F(FeatureListTest, GetFeatureOverrides_UseDefault) {
+ ClearFeatureListInstance();
+ FieldTrialList field_trial_list(nullptr);
+ scoped_ptr<FeatureList> feature_list(new FeatureList);
+ feature_list->InitializeFromCommandLine("A,X", "D");
+
+ FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
+ feature_list->RegisterFieldTrialOverride(
+ kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
+
+ RegisterFeatureListInstance(std::move(feature_list));
+
+ std::string enable_features;
+ std::string disable_features;
+ FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
+ &disable_features);
+ EXPECT_EQ("*OffByDefault<Trial,A,X", SortFeatureListString(enable_features));
+ EXPECT_EQ("D", SortFeatureListString(disable_features));
+}
+
TEST_F(FeatureListTest, InitializeFromCommandLine_WithFieldTrials) {
ClearFeatureListInstance();
FieldTrialList field_trial_list(nullptr);
@@ -385,4 +405,23 @@ TEST_F(FeatureListTest, InitializeFromCommandLine_WithFieldTrials) {
EXPECT_TRUE(FieldTrialList::IsTrialActive("Trial"));
}
+TEST_F(FeatureListTest, InitializeFromCommandLine_UseDefault) {
+ ClearFeatureListInstance();
+ FieldTrialList field_trial_list(nullptr);
+ FieldTrialList::CreateFieldTrial("T1", "Group");
+ FieldTrialList::CreateFieldTrial("T2", "Group");
+ scoped_ptr<FeatureList> feature_list(new FeatureList);
+ feature_list->InitializeFromCommandLine(
+ "A,*OffByDefault<T1,*OnByDefault<T2,X", "D");
+ RegisterFeatureListInstance(std::move(feature_list));
+
+ EXPECT_FALSE(FieldTrialList::IsTrialActive("T1"));
+ EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
+ EXPECT_TRUE(FieldTrialList::IsTrialActive("T1"));
+
+ EXPECT_FALSE(FieldTrialList::IsTrialActive("T2"));
+ EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
+ EXPECT_TRUE(FieldTrialList::IsTrialActive("T2"));
+}
+
} // namespace base