summaryrefslogtreecommitdiffstats
path: root/components/search
diff options
context:
space:
mode:
authormukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-23 08:48:40 +0000
committermukai@chromium.org <mukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-23 08:48:40 +0000
commit720b10490523188c34b012d1ccf2059020cc13e1 (patch)
treeb772fe2125597d0bb8e57dfdbc3b9aa5d9b498c3 /components/search
parent86487aa3a77b454917b5a1cb0c42b05cb6b22136 (diff)
downloadchromium_src-720b10490523188c34b012d1ccf2059020cc13e1.zip
chromium_src-720b10490523188c34b012d1ccf2059020cc13e1.tar.gz
chromium_src-720b10490523188c34b012d1ccf2059020cc13e1.tar.bz2
Moves some functions in search.h to components.
These functions are simplistic and doesn't depend on chrome's feature, so there's no reason to be under chrome/browser. Moving to components/ would help further componentization task of autocomplete anad omnibox_field_trials. BUG=371538 R=brettw@chromium.org, pkasting@chromium.org, blundell@chromium.org TBR=tedchoc@chromium.org, jhawkins@chromium.org TEST=build Review URL: https://codereview.chromium.org/393173002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284885 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/search')
-rw-r--r--components/search/BUILD.gn16
-rw-r--r--components/search/DEPS3
-rw-r--r--components/search/OWNERS4
-rw-r--r--components/search/search.cc146
-rw-r--r--components/search/search.h59
-rw-r--r--components/search/search_android_unittest.cc30
-rw-r--r--components/search/search_switches.cc16
-rw-r--r--components/search/search_switches.h18
-rw-r--r--components/search/search_unittest.cc133
9 files changed, 425 insertions, 0 deletions
diff --git a/components/search/BUILD.gn b/components/search/BUILD.gn
new file mode 100644
index 0000000..a895701
--- /dev/null
+++ b/components/search/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2014 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.
+
+static_library("search") {
+ sources = [
+ "search.cc",
+ "search.h",
+ "search_switches.cc",
+ "search_switches.h",
+ ]
+
+ deps = [
+ "//base",
+ ]
+}
diff --git a/components/search/DEPS b/components/search/DEPS
new file mode 100644
index 0000000..80f6f90
--- /dev/null
+++ b/components/search/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+components/variations",
+]
diff --git a/components/search/OWNERS b/components/search/OWNERS
new file mode 100644
index 0000000..a7265f6
--- /dev/null
+++ b/components/search/OWNERS
@@ -0,0 +1,4 @@
+kmadhusu@chromium.org
+brettw@chromium.org
+jered@chromium.org
+samarth@chromium.org
diff --git a/components/search/search.cc b/components/search/search.cc
new file mode 100644
index 0000000..8689e51
--- /dev/null
+++ b/components/search/search.cc
@@ -0,0 +1,146 @@
+// Copyright 2014 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
diff --git a/components/search/search.h b/components/search/search.h
new file mode 100644
index 0000000..df27e60
--- /dev/null
+++ b/components/search/search.h
@@ -0,0 +1,59 @@
+// Copyright 2014 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.
+
+#ifndef COMPONENTS_SEARCH_SEARCH_H_
+#define COMPONENTS_SEARCH_SEARCH_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/strings/string16.h"
+
+namespace chrome {
+
+// Returns whether the Instant Extended API is enabled.
+bool IsInstantExtendedAPIEnabled();
+
+// Returns the value to pass to the &espv CGI parameter when loading the
+// embedded search page from the user's default search provider. Returns 0 if
+// the Instant Extended API is not enabled.
+uint64 EmbeddedSearchPageVersion();
+
+// Type for a collection of experiment configuration parameters.
+typedef std::vector<std::pair<std::string, std::string> > FieldTrialFlags;
+
+// Finds the active field trial group name and parses out the configuration
+// flags. On success, |flags| will be filled with the field trial flags. |flags|
+// must not be NULL. Returns true iff the active field trial is successfully
+// parsed and not disabled.
+// Note that |flags| may be successfully populated in some cases when false is
+// returned - in these cases it should not be used.
+// Exposed for testing only.
+bool GetFieldTrialInfo(FieldTrialFlags* flags);
+
+// Given a FieldTrialFlags object, returns the string value of the provided
+// flag.
+// Exposed for testing only.
+std::string GetStringValueForFlagWithDefault(const std::string& flag,
+ const std::string& default_value,
+ const FieldTrialFlags& flags);
+
+// Given a FieldTrialFlags object, returns the uint64 value of the provided
+// flag.
+// Exposed for testing only.
+uint64 GetUInt64ValueForFlagWithDefault(const std::string& flag,
+ uint64 default_value,
+ const FieldTrialFlags& flags);
+
+// Given a FieldTrialFlags object, returns the bool value of the provided flag.
+// Exposed for testing only.
+bool GetBoolValueForFlagWithDefault(const std::string& flag,
+ bool default_value,
+ const FieldTrialFlags& flags);
+
+} // namespace chrome
+
+#endif // COMPONENTS_SEARCH_SEARCH_H_
diff --git a/components/search/search_android_unittest.cc b/components/search/search_android_unittest.cc
new file mode 100644
index 0000000..9c67edff
--- /dev/null
+++ b/components/search/search_android_unittest.cc
@@ -0,0 +1,30 @@
+// Copyright 2014 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/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/statistics_recorder.h"
+#include "components/search/search_switches.h"
+#include "components/variations/entropy_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome {
+
+namespace {
+
+TEST(SearchTest, EmbeddedSearchAPIEnabled) {
+ EXPECT_EQ(1ul, EmbeddedSearchPageVersion());
+ EXPECT_FALSE(IsInstantExtendedAPIEnabled());
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableEmbeddedSearchAPI);
+ EXPECT_EQ(2ul, EmbeddedSearchPageVersion());
+ EXPECT_TRUE(IsInstantExtendedAPIEnabled());
+}
+
+} // namespace
+
+} // namespace chrome
diff --git a/components/search/search_switches.cc b/components/search/search_switches.cc
new file mode 100644
index 0000000..9359725
--- /dev/null
+++ b/components/search/search_switches.cc
@@ -0,0 +1,16 @@
+// Copyright 2014 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_switches.h"
+
+namespace switches {
+
+#if defined(OS_ANDROID)
+
+// Enables EmbeddedSearch API in the search results page.
+const char kEnableEmbeddedSearchAPI[] = "enable-embeddedsearch-api";
+
+#endif
+
+} // namespace switches
diff --git a/components/search/search_switches.h b/components/search/search_switches.h
new file mode 100644
index 0000000..48b50c1
--- /dev/null
+++ b/components/search/search_switches.h
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+#ifndef COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
+#define COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
+
+#include "build/build_config.h"
+
+namespace switches {
+
+#if defined(OS_ANDROID)
+extern const char kEnableEmbeddedSearchAPI[];
+#endif
+
+} // namespace switches
+
+#endif // COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
diff --git a/components/search/search_unittest.cc b/components/search/search_unittest.cc
new file mode 100644
index 0000000..b8c4e1d
--- /dev/null
+++ b/components/search/search_unittest.cc
@@ -0,0 +1,133 @@
+// Copyright 2014 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/metrics/field_trial.h"
+#include "base/metrics/statistics_recorder.h"
+#include "components/variations/entropy_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chrome {
+
+class EmbeddedSearchFieldTrialTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ field_trial_list_.reset(new base::FieldTrialList(
+ new metrics::SHA1EntropyProvider("42")));
+ base::StatisticsRecorder::Initialize();
+ }
+
+ private:
+ scoped_ptr<base::FieldTrialList> field_trial_list_;
+};
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoEmptyAndValid) {
+ FieldTrialFlags flags;
+
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidNumber) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77.2"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoInvalidName) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Invalid77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidGroup) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoValidFlag) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewName) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoNewNameOverridesOld) {
+ FieldTrialFlags flags;
+
+ EXPECT_EQ(9999ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
+ "Group77 foo:6"));
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
+ "Group78 foo:5"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(1ul, flags.size());
+ EXPECT_EQ(6ul, GetUInt64ValueForFlagWithDefault("foo", 9999, flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoLotsOfFlags) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(3ul, flags.size());
+ EXPECT_EQ(true, GetBoolValueForFlagWithDefault("bar", false, flags));
+ EXPECT_EQ(7ul, GetUInt64ValueForFlagWithDefault("baz", 0, flags));
+ EXPECT_EQ("dogs",
+ GetStringValueForFlagWithDefault("cat", std::string(), flags));
+ EXPECT_EQ("default",
+ GetStringValueForFlagWithDefault("moose", "default", flags));
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoDisabled) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Group77 bar:1 baz:7 cat:dogs DISABLED"));
+ EXPECT_FALSE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(0ul, flags.size());
+}
+
+TEST_F(EmbeddedSearchFieldTrialTest, GetFieldTrialInfoControlFlags) {
+ FieldTrialFlags flags;
+
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
+ "EmbeddedSearch", "Control77 bar:1 baz:7 cat:dogs"));
+ EXPECT_TRUE(GetFieldTrialInfo(&flags));
+ EXPECT_EQ(3ul, flags.size());
+}
+
+} // namespace chrome