Chromium Code Reviews| Index: chrome/browser/ui/search/search.cc |
| diff --git a/chrome/browser/ui/search/search.cc b/chrome/browser/ui/search/search.cc |
| index 1205dfb9c67950c58dd4f1d2f0ac7c8a6dd8ea86..35f14c3185b6cde1edb39edaeb9959c2ab40e14d 100644 |
| --- a/chrome/browser/ui/search/search.cc |
| +++ b/chrome/browser/ui/search/search.cc |
| @@ -7,37 +7,142 @@ |
| #include "base/command_line.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/string_number_conversions.h" |
| +#include "base/string_split.h" |
| #include "base/string_util.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/themes/theme_service.h" |
| +#include "chrome/browser/themes/theme_service_factory.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/chrome_version_info.h" |
| namespace chrome { |
| namespace search { |
| -bool IsInstantExtendedAPIEnabled(const Profile* profile) { |
| +// Configuration options for Embedded Search. |
| +// InstantExtended field trials are named in such a way that we can parse out |
| +// the experiment configuration from the trial's group name in order to give |
| +// us maximum flexability in running experiments. |
| +// Field trials should be named things like "Group7 espv:2 themes:0" - |
|
dhollowa
2013/01/04 17:11:49
nit: period "." at end of sentence, not "-".
David Black
2013/01/04 19:55:32
Done.
|
| +// The first token is always GroupN for some integer N, followed by a |
| +// space-delimited list of key:value pairs which correspond to these flags: |
| +const char kEnableOnThemesFlagName[] = "themes"; |
| +const bool kEnableOnThemesDefault = false; |
| + |
| +const char kEmbeddedPageVersionFlagName[] = "espv"; |
| +const int kEmbeddedPageVersionDefault = 1; |
| + |
| +// Constants for the field trial name and group prefix. |
| +const char kInstantExtendedFieldTrialName[] = "InstantExtended"; |
| +const char kGroupNumberPrefix[] = "Group"; |
| + |
| +// If the field trial's group name ends with this string its configuration will |
| +// be ignored and Instant Extended will not be enabled by default. |
| +const char kDisablingSuffix[] = "DISABLED"; |
| + |
| +// Given a field trial group name in the above format, parses out the group |
| +// number and configuration flags. Will return a group number of 0 on error. |
| +void GetFieldTrialInfo(const std::string& group_name, |
| + FieldTrialFlags* flags, |
| + uint64* group_number) { |
| + if (!EndsWith(group_name, kDisablingSuffix, true) && |
| + StartsWithASCII(group_name, kGroupNumberPrefix, true)) { |
| + // We have a valid trial that starts with "Group" and isn't disabled. |
| + size_t first_space = group_name.find(" "); |
| + std::string group_prefix = group_name; |
| + if (first_space != std::string::npos) { |
| + // There is a flags section of the group name. Split that out and parse |
| + // it. |
| + group_prefix = group_name.substr(0, first_space); |
| + base::SplitStringIntoKeyValuePairs( |
| + group_name.substr(first_space), ':', ' ', flags); |
| + } |
| + if (!base::StringToUint64(group_prefix.substr(strlen(kGroupNumberPrefix)), |
| + group_number)) { |
| + // Could not parse group number. |
| + *group_number = 0; |
| + } |
| + } |
| +} |
| + |
| +// Given a FieldTrialFlags object, returns the string value of the provided |
| +// flag. |
| +std::string GetStringValueForFlagWithDefault( |
| + const std::string& flag, |
| + const std::string& default_value, |
| + FieldTrialFlags& flags) { |
| + FieldTrialFlags::const_iterator i; |
| + for (i = flags.begin(); i != flags.end(); i++) { |
| + if (i->first == flag) |
| + return i->second; |
| + } |
| + return default_value; |
| +} |
| + |
| +// Given a FieldTrialFlags object, returns the uint64 value of the provided |
| +// flag. |
| +uint64 GetUInt64ValueForFlagWithDefault( |
| + const std::string& flag, uint64 default_value, FieldTrialFlags& flags) { |
| + uint64 value; |
| + if (!base::StringToUint64(GetStringValueForFlagWithDefault(flag, "", flags), |
| + &value)) |
| + return default_value; |
| + return value; |
| +} |
| + |
| +// Given a FieldTrialFlags object, returns the boolean value of the provided |
| +// flag. |
| +bool GetBoolValueForFlagWithDefault( |
| + const std::string& flag, bool default_value, FieldTrialFlags& flags) { |
| + return GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags); |
| +} |
| + |
| +// Check whether or not the Extended API should be used on the given profile. |
| +bool IsInstantExtendedAPIEnabled(Profile* profile) { |
| return EmbeddedSearchPageVersion(profile) != 0; |
| } |
| -uint64 EmbeddedSearchPageVersion(const Profile* profile) { |
| +// Determine what embedded search page version to request from the user's |
| +// default search provider. If 0, the embedded search UI should not be enabled. |
| +// Note that the profile object here isn't const because we need to determine |
| +// whether or not the user has a theme installed as part of this check, and |
| +// that logic requires a non-const profile for whatever reason. |
| +uint64 EmbeddedSearchPageVersion(Profile* profile) { |
| // Incognito windows do not currently use the embedded search API. |
| if (!profile || profile->IsOffTheRecord()) |
| return 0; |
| // Check Finch field trials. |
| - base::FieldTrial* trial = base::FieldTrialList::Find("InstantExtended"); |
| - if (trial && StartsWithASCII(trial->group_name(), "Group", true)) { |
| - uint64 group_number; |
| - if (base::StringToUint64(trial->group_name().substr(5), &group_number)) { |
| - return group_number; |
| - } |
| + FieldTrialFlags flags; |
| + uint64 group_number = 0; |
| + base::FieldTrial* trial = |
| + base::FieldTrialList::Find(kInstantExtendedFieldTrialName); |
| + if (trial) { |
| + std::string group_name = trial->group_name(); |
| + GetFieldTrialInfo(group_name, &flags, &group_number); |
| + } |
| + |
| + if (group_number > 0) { |
| + uint64 espv = GetUInt64ValueForFlagWithDefault( |
| + kEmbeddedPageVersionFlagName, |
| + kEmbeddedPageVersionDefault, |
| + flags); |
| + |
| + // Check for themes. |
| + bool has_theme = |
| + !ThemeServiceFactory::GetForProfile(profile)->UsingDefaultTheme(); |
| + bool enable_for_themes = |
| + GetBoolValueForFlagWithDefault(kEnableOnThemesFlagName, |
| + kEnableOnThemesDefault, |
| + flags); |
| + if (!has_theme || enable_for_themes) |
| + return espv; |
| } |
| if (CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableInstantExtendedAPI)) { |
| // The user has manually flipped the about:flags switch - give the default |
| // UI version. |
| - return 1; |
| + return kEmbeddedPageVersionDefault; |
| } |
| return 0; |
| } |
| @@ -47,7 +152,7 @@ void EnableInstantExtendedAPIForTesting() { |
| switches::kEnableInstantExtendedAPI); |
| } |
| -bool IsQueryExtractionEnabled(const Profile* profile) { |
| +bool IsQueryExtractionEnabled(Profile* profile) { |
| return IsInstantExtendedAPIEnabled(profile) || |
| CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kEnableInstantExtendedAPI); |