| Index: components/search/search.cc
|
| diff --git a/components/search/search.cc b/components/search/search.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2f1c1d388651b369da48c6be8c2677565b7b6e1a
|
| --- /dev/null
|
| +++ b/components/search/search.cc
|
| @@ -0,0 +1,146 @@
|
| +// Copyright 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/search/search.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/metrics/field_trial.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/string_split.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "components/search/search_switches.h"
|
| +
|
| +namespace chrome {
|
| +
|
| +namespace {
|
| +
|
| +// Configuration options for Embedded Search.
|
| +// EmbeddedSearch 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 trial groups should be named things like "Group7 espv:2 instant:1".
|
| +// 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 kEmbeddedPageVersionFlagName[] = "espv";
|
| +
|
| +#if defined(OS_IOS)
|
| +const uint64 kEmbeddedPageVersionDefault = 1;
|
| +#elif defined(OS_ANDROID)
|
| +const uint64 kEmbeddedPageVersionDefault = 1;
|
| +// Use this variant to enable EmbeddedSearch SearchBox API in the results page.
|
| +const uint64 kEmbeddedSearchEnabledVersion = 2;
|
| +#else
|
| +const uint64 kEmbeddedPageVersionDefault = 2;
|
| +#endif
|
| +
|
| +// Constants for the field trial name and group prefix.
|
| +// Note in M30 and below this field trial was named "InstantExtended" and in
|
| +// M31 was renamed to EmbeddedSearch for clarity and cleanliness. Since we
|
| +// can't easilly sync up Finch configs with the pushing of this change to
|
| +// Dev & Canary, for now the code accepts both names.
|
| +// TODO(dcblack): Remove the InstantExtended name once M31 hits the Beta
|
| +// channel.
|
| +const char kInstantExtendedFieldTrialName[] = "InstantExtended";
|
| +const char kEmbeddedSearchFieldTrialName[] = "EmbeddedSearch";
|
| +
|
| +// 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";
|
| +
|
| +} // namespace
|
| +
|
| +bool IsInstantExtendedAPIEnabled() {
|
| +#if defined(OS_IOS)
|
| + return false;
|
| +#elif defined(OS_ANDROID)
|
| + return EmbeddedSearchPageVersion() == kEmbeddedSearchEnabledVersion;
|
| +#else
|
| + return true;
|
| +#endif // defined(OS_IOS)
|
| +}
|
| +
|
| +// 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.
|
| +uint64 EmbeddedSearchPageVersion() {
|
| +#if defined(OS_ANDROID)
|
| + if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableEmbeddedSearchAPI)) {
|
| + return kEmbeddedSearchEnabledVersion;
|
| + }
|
| +#endif
|
| +
|
| + FieldTrialFlags flags;
|
| + if (GetFieldTrialInfo(&flags)) {
|
| + return GetUInt64ValueForFlagWithDefault(kEmbeddedPageVersionFlagName,
|
| + kEmbeddedPageVersionDefault,
|
| + flags);
|
| + }
|
| + return kEmbeddedPageVersionDefault;
|
| +}
|
| +
|
| +bool GetFieldTrialInfo(FieldTrialFlags* flags) {
|
| + // Get the group name. If the EmbeddedSearch trial doesn't exist, look for
|
| + // the older InstantExtended name.
|
| + std::string group_name = base::FieldTrialList::FindFullName(
|
| + kEmbeddedSearchFieldTrialName);
|
| + if (group_name.empty()) {
|
| + group_name = base::FieldTrialList::FindFullName(
|
| + kInstantExtendedFieldTrialName);
|
| + }
|
| +
|
| + if (EndsWith(group_name, kDisablingSuffix, true))
|
| + return false;
|
| +
|
| + // We have a valid trial that isn't disabled. Extract the flags.
|
| + std::string group_prefix(group_name);
|
| + size_t first_space = group_name.find(" ");
|
| + 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);
|
| + if (!base::SplitStringIntoKeyValuePairs(group_name.substr(first_space),
|
| + ':', ' ', flags)) {
|
| + // Failed to parse the flags section. Assume the whole group name is
|
| + // invalid.
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +// Given a FieldTrialFlags object, returns the string value of the provided
|
| +// flag.
|
| +std::string GetStringValueForFlagWithDefault(const std::string& flag,
|
| + const std::string& default_value,
|
| + const 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,
|
| + const FieldTrialFlags& flags) {
|
| + uint64 value;
|
| + std::string str_value =
|
| + GetStringValueForFlagWithDefault(flag, std::string(), flags);
|
| + if (base::StringToUint64(str_value, &value))
|
| + return value;
|
| + return default_value;
|
| +}
|
| +
|
| +// Given a FieldTrialFlags object, returns the boolean value of the provided
|
| +// flag.
|
| +bool GetBoolValueForFlagWithDefault(const std::string& flag,
|
| + bool default_value,
|
| + const FieldTrialFlags& flags) {
|
| + return !!GetUInt64ValueForFlagWithDefault(flag, default_value ? 1 : 0, flags);
|
| +}
|
| +
|
| +} // namespace chrome
|
|
|